Backed out changeset b46c006a7696 (bug 716859) and changeset 6a14e4c15aa6 (bug 841836) for B2G test failures on a CLOSED TREE.
authorRyan VanderMeulen <ryanvm@gmail.com>
Wed, 20 Feb 2013 10:01:20 -0500
changeset 132858 f04919e7789fc6b7977aec2d3fbd5519dbd9360f
parent 132857 3f2b219950b82780be2c88320ec4a7852b3c4988
child 132859 fa3150c558e0eebbc87d53caa7418330574a78db
push id2452
push userlsblakk@mozilla.com
push dateMon, 13 May 2013 16:59:38 +0000
treeherdermozilla-beta@d4b152d29d8d [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
bugs716859, 841836
milestone22.0a1
backs outb46c006a7696832b2763b13f3934a226510db373
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Backed out changeset b46c006a7696 (bug 716859) and changeset 6a14e4c15aa6 (bug 841836) for B2G test failures on a CLOSED TREE.
b2g/test/emulator.manifest
content/canvas/src/WebGLContext.cpp
content/canvas/src/WebGLContext.h
content/canvas/src/WebGLContextGL.cpp
content/canvas/src/WebGLFramebuffer.cpp
content/canvas/test/reftest/reftest.list
dom/bindings/test/test_integers.html
dom/plugins/base/nsNPAPIPluginInstance.cpp
gfx/gl/GLContext.cpp
gfx/gl/GLContext.h
gfx/gl/GLContextProvider.h
gfx/gl/GLContextProviderCGL.mm
gfx/gl/GLContextProviderEGL.cpp
gfx/gl/GLContextProviderGLX.cpp
gfx/gl/GLContextProviderImpl.h
gfx/gl/GLContextProviderNull.cpp
gfx/gl/GLContextProviderWGL.cpp
gfx/gl/GLContextSymbols.h
gfx/gl/GLContextTypes.cpp
gfx/gl/GLContextTypes.h
gfx/gl/GLContextUtils.cpp
gfx/gl/GLDefs.h
gfx/gl/GLLibraryEGL.cpp
gfx/gl/GLLibraryEGL.h
gfx/gl/GLScreenBuffer.cpp
gfx/gl/GLScreenBuffer.h
gfx/gl/GLXLibrary.h
gfx/gl/Makefile.in
gfx/gl/SharedSurface.cpp
gfx/gl/SharedSurface.h
gfx/gl/SharedSurfaceANGLE.cpp
gfx/gl/SharedSurfaceANGLE.h
gfx/gl/SharedSurfaceEGL.cpp
gfx/gl/SharedSurfaceEGL.h
gfx/gl/SharedSurfaceGL.cpp
gfx/gl/SharedSurfaceGL.h
gfx/gl/SurfaceFactory.cpp
gfx/gl/SurfaceFactory.h
gfx/gl/SurfaceStream.cpp
gfx/gl/SurfaceStream.h
gfx/gl/SurfaceTypes.h
gfx/layers/Layers.h
gfx/layers/basic/BasicCanvasLayer.cpp
gfx/layers/d3d10/CanvasLayerD3D10.cpp
gfx/layers/d3d10/CanvasLayerD3D10.h
gfx/layers/d3d9/CanvasLayerD3D9.cpp
gfx/layers/ipc/LayersSurfaces.ipdlh
gfx/layers/opengl/CanvasLayerOGL.cpp
gfx/layers/opengl/CanvasLayerOGL.h
gfx/layers/opengl/ImageLayerOGL.cpp
gfx/layers/opengl/LayerManagerOGL.cpp
gfx/thebes/gfxUtils.cpp
modules/libpref/src/init/all.js
--- a/b2g/test/emulator.manifest
+++ b/b2g/test/emulator.manifest
@@ -1,6 +1,6 @@
 [{
-"size": 606070399,
-"digest": "3d3899e2537bee5e3f969bb6d0e90fed93345512123e3133b1de793d59a8993d8174d9456cb92d86a880f6813d6049933de924cd522a433ef26c4bfa997777a7",
+"size": 608318343,
+"digest": "9ab6487eccf44b0781cc96c2af9ba497f720a8d289bde40e29417f9db82788d6c8653c7dafa7443069f5898635eef45fa048ee99c03a9d0113c019a2f80f5aa8",
 "algorithm": "sha512",
 "filename": "emulator.zip"
 }]
--- a/content/canvas/src/WebGLContext.cpp
+++ b/content/canvas/src/WebGLContext.cpp
@@ -45,20 +45,19 @@
 #include "mozilla/Services.h"
 #include "mozilla/dom/WebGLRenderingContextBinding.h"
 #include "mozilla/dom/BindingUtils.h"
 #include "mozilla/dom/ipc/ProcessPriorityManager.h"
 
 #include "Layers.h"
 
 using namespace mozilla;
+using namespace mozilla::gl;
 using namespace mozilla::dom;
 using namespace mozilla::dom::ipc;
-using namespace mozilla::gfx;
-using namespace mozilla::gl;
 using namespace mozilla::layers;
 
 NS_IMETHODIMP
 WebGLMemoryPressureObserver::Observe(nsISupports* aSubject,
                                      const char* aTopic,
                                      const PRUnichar* aSomeData)
 {
     if (strcmp(aTopic, "memory-pressure"))
@@ -105,17 +104,16 @@ WebGLContextOptions::WebGLContextOptions
 
 WebGLContext::WebGLContext()
     : gl(nullptr)
 {
     SetIsDOMBinding();
 
     mGeneration = 0;
     mInvalidated = false;
-    mShouldPresent = true;
     mResetLayer = true;
     mOptionsFrozen = false;
 
     mActiveTexture = 0;
     mWebGLError = LOCAL_GL_NO_ERROR;
     mPixelStoreFlipY = false;
     mPixelStorePremultiplyAlpha = false;
     mPixelStoreColorspaceConversion = BROWSER_DEFAULT_WEBGL;
@@ -153,16 +151,17 @@ WebGLContext::WebGLContext()
     mStencilRefBack = 0;
     mStencilValueMaskFront = 0xffffffff;
     mStencilValueMaskBack  = 0xffffffff;
     mStencilWriteMaskFront = 0xffffffff;
     mStencilWriteMaskBack  = 0xffffffff;
 
     mScissorTestEnabled = 0;
     mDitherEnabled = 1;
+    mBackbufferClearingStatus = BackbufferClearingStatus::NotClearedSinceLastPresented;
     
     // initialize some GL values: we're going to get them from the GL and use them as the sizes of arrays,
     // so in case glGetIntegerv leaves them uninitialized because of a GL bug, we would have very weird crashes.
     mGLMaxVertexAttribs = 0;
     mGLMaxTextureUnits = 0;
     mGLMaxTextureSize = 0;
     mGLMaxCubeMapTextureSize = 0;
     mGLMaxRenderbufferSize = 0;
@@ -189,18 +188,16 @@ WebGLContext::WebGLContext()
 
     mAlreadyGeneratedWarnings = 0;
     mAlreadyWarnedAboutFakeVertexAttrib0 = false;
 
     mLastUseIndex = 0;
 
     mMinInUseAttribArrayLengthCached = false;
     mMinInUseAttribArrayLength = 0;
-
-    mIsScreenCleared = false;
 }
 
 WebGLContext::~WebGLContext()
 {
     DestroyResourcesAndContext();
     WebGLMemoryMultiReporterWrapper::RemoveWebGLContext(this);
     TerminateContextLossTimer();
     mContextRestorer = nullptr;
@@ -380,23 +377,21 @@ WebGLContext::SetDimensions(int32_t widt
     // If we already have a gl context, then we just need to resize it
     if (gl) {
         MakeContextCurrent();
 
         gl->ResizeOffscreen(gfxIntSize(width, height)); // Doesn't matter if it succeeds (soft-fail)
         // It's unlikely that we'll get a proper-sized context if we recreate if we didn't on resize
 
         // everything's good, we're done here
-        mWidth = gl->OffscreenSize().width;
-        mHeight = gl->OffscreenSize().height;
+        mWidth = gl->OffscreenActualSize().width;
+        mHeight = gl->OffscreenActualSize().height;
         mResetLayer = true;
 
-        ScopedBindFramebuffer autoFB(gl, 0);
         gl->ClearSafely();
-        mShouldPresent = true;
 
         return NS_OK;
     }
 
     // End of early return cases.
     // At this point we know that we're not just resizing an existing context,
     // we are initializing a new context.
 
@@ -436,40 +431,65 @@ WebGLContext::SetDimensions(int32_t widt
     // event.
 
     // If incrementing the generation would cause overflow,
     // don't allow it.  Allowing this would allow us to use
     // resource handles created from older context generations.
     if (!(mGeneration + 1).isValid())
         return NS_ERROR_FAILURE; // exit without changing the value of mGeneration
 
-    SurfaceCaps caps;
+    gl::ContextFormat format(gl::ContextFormat::BasicRGBA32);
+    if (mOptions.depth) {
+        format.depth = 24;
+        format.minDepth = 16;
+    }
 
-    caps.color = true;
-    caps.alpha = mOptions.alpha;
-    caps.depth = mOptions.depth;
-    caps.stencil = mOptions.stencil;
+    if (mOptions.stencil) {
+        format.stencil = 8;
+        format.minStencil = 8;
+    }
+
+    if (!mOptions.alpha) {
+        format.alpha = 0;
+        format.minAlpha = 0;
+    }
 
     // we should really have this behind a
     // |gfxPlatform::GetPlatform()->GetScreenDepth() == 16| check, but
     // for now it's just behind a pref for testing/evaluation.
-    caps.bpp16 = prefer16bit;
-
-    caps.preserve = mOptions.preserveDrawingBuffer;
+    if (prefer16bit) {
+        // Select 4444 or 565 on 16-bit displays; we won't/shouldn't
+        // hit this on the desktop, but let mobile know we're ok with
+        // it.  Note that we don't just set this to 4440 if no alpha,
+        // because that might cause us to choose 4444 anyway and we
+        // don't want that.
+        if (mOptions.alpha) {
+            format.red = 4;
+            format.green = 4;
+            format.blue = 4;
+            format.alpha = 4;
+        } else {
+            format.red = 5;
+            format.green = 6;
+            format.blue = 5;
+            format.alpha = 0;
+        }
+    }
 
     bool forceMSAA =
         Preferences::GetBool("webgl.msaa-force", false);
 
     int32_t status;
     nsCOMPtr<nsIGfxInfo> gfxInfo = do_GetService("@mozilla.org/gfx/info;1");
     if (mOptions.antialias &&
         gfxInfo &&
         NS_SUCCEEDED(gfxInfo->GetFeatureStatus(nsIGfxInfo::FEATURE_WEBGL_MSAA, &status))) {
         if (status == nsIGfxInfo::FEATURE_NO_INFO || forceMSAA) {
-            caps.antialias = true;
+            uint32_t msaaLevel = Preferences::GetUint("webgl.msaa-level", 2);
+            format.samples = msaaLevel*msaaLevel;
         }
     }
 
 #ifdef XP_WIN
     if (PR_GetEnv("MOZ_WEBGL_PREFER_EGL")) {
         preferEGL = true;
     }
 #endif
@@ -500,35 +520,34 @@ WebGLContext::SetDimensions(int32_t widt
     // allow forcing GL and not EGL/ANGLE
     if (useMesaLlvmPipe || PR_GetEnv("MOZ_WEBGL_FORCE_OPENGL")) {
         preferEGL = false;
         useANGLE = false;
         useOpenGL = true;
     }
 #endif
 
-    gfxIntSize size(width, height);
-
 #ifdef XP_WIN
     // if we want EGL, try it now
     if (!gl && (preferEGL || useANGLE) && !preferOpenGL) {
-        gl = gl::GLContextProviderEGL::CreateOffscreen(size, caps);
+        gl = gl::GLContextProviderEGL::CreateOffscreen(gfxIntSize(width, height), format);
         if (!gl || !InitAndValidateGL()) {
             GenerateWarning("Error during ANGLE OpenGL ES initialization");
             return NS_ERROR_FAILURE;
         }
     }
 #endif
 
     // try the default provider, whatever that is
     if (!gl && useOpenGL) {
         GLContext::ContextFlags flag = useMesaLlvmPipe 
                                        ? GLContext::ContextFlagsMesaLLVMPipe
                                        : GLContext::ContextFlagsNone;
-        gl = gl::GLContextProvider::CreateOffscreen(size, caps, flag);
+        gl = gl::GLContextProvider::CreateOffscreen(gfxIntSize(width, height), 
+                                                               format, flag);
         if (gl && !InitAndValidateGL()) {
             GenerateWarning("Error during %s initialization", 
                             useMesaLlvmPipe ? "Mesa LLVMpipe" : "OpenGL");
             return NS_ERROR_FAILURE;
         }
     }
 
     if (!gl) {
@@ -557,34 +576,25 @@ WebGLContext::SetDimensions(int32_t widt
         // XXX dispatch context lost event
     }
 #endif
 
     MakeContextCurrent();
 
     // Make sure that we clear this out, otherwise
     // we'll end up displaying random memory
-    gl->fBindFramebuffer(LOCAL_GL_FRAMEBUFFER, 0);
+    gl->fBindFramebuffer(LOCAL_GL_FRAMEBUFFER, gl->GetOffscreenFBO());
 
     gl->fViewport(0, 0, mWidth, mHeight);
     gl->fClearColor(0.0f, 0.0f, 0.0f, 0.0f);
     gl->fClearDepth(1.0f);
     gl->fClearStencil(0);
 
     gl->ClearSafely();
 
-    mShouldPresent = true;
-
-    MOZ_ASSERT(gl->Caps().color == caps.color);
-    MOZ_ASSERT(gl->Caps().alpha == caps.alpha);
-    MOZ_ASSERT(gl->Caps().depth == caps.depth || !gl->Caps().depth);
-    MOZ_ASSERT(gl->Caps().stencil == caps.stencil || !gl->Caps().stencil);
-    MOZ_ASSERT(gl->Caps().antialias == caps.antialias || !gl->Caps().antialias);
-    MOZ_ASSERT(gl->Caps().preserve == caps.preserve);
-
     reporter.SetSuccessful();
     return NS_OK;
 }
 
 NS_IMETHODIMP
 WebGLContext::Render(gfxContext *ctx, gfxPattern::GraphicsFilter f, uint32_t aFlags)
 {
     if (!gl)
@@ -788,49 +798,35 @@ void WebGLContext::UpdateLastUseIndex()
 
 static uint8_t gWebGLLayerUserData;
 
 namespace mozilla {
 
 class WebGLContextUserData : public LayerUserData {
 public:
     WebGLContextUserData(HTMLCanvasElement *aContent)
-        : mContent(aContent)
-    {}
-
-    /* PreTransactionCallback gets called by the Layers code every time the
-     * WebGL canvas is going to be composited.
-     */
-    static void PreTransactionCallback(void* data)
-    {
-        WebGLContextUserData* userdata = static_cast<WebGLContextUserData*>(data);
-        HTMLCanvasElement* canvas = userdata->mContent;
-        WebGLContext* context = static_cast<WebGLContext*>(canvas->GetContextAtIndex(0));
+    : mContent(aContent) {}
 
-        // Present our screenbuffer, if needed.
-        context->PresentScreenBuffer();
-    }
+  /** DidTransactionCallback gets called by the Layers code everytime the WebGL canvas gets composite,
+    * so it really is the right place to put actions that have to be performed upon compositing
+    */
+  static void DidTransactionCallback(void* aData)
+  {
+    WebGLContextUserData *userdata = static_cast<WebGLContextUserData*>(aData);
+    HTMLCanvasElement *canvas = userdata->mContent;
+    WebGLContext *context = static_cast<WebGLContext*>(canvas->GetContextAtIndex(0));
 
-    /** DidTransactionCallback gets called by the Layers code everytime the WebGL canvas gets composite,
-      * so it really is the right place to put actions that have to be performed upon compositing
-      */
-    static void DidTransactionCallback(void* aData)
-    {
-        WebGLContextUserData *userdata = static_cast<WebGLContextUserData*>(aData);
-        HTMLCanvasElement *canvas = userdata->mContent;
-        WebGLContext *context = static_cast<WebGLContext*>(canvas->GetContextAtIndex(0));
+    context->mBackbufferClearingStatus = BackbufferClearingStatus::NotClearedSinceLastPresented;
+    canvas->MarkContextClean();
 
-        // Mark ourselves as no longer invalidated.
-        context->MarkContextClean();
-
-        context->UpdateLastUseIndex();
-    }
+    context->UpdateLastUseIndex();
+  }
 
 private:
-    nsRefPtr<HTMLCanvasElement> mContent;
+  nsRefPtr<HTMLCanvasElement> mContent;
 };
 
 } // end namespace mozilla
 
 already_AddRefed<layers::CanvasLayer>
 WebGLContext::GetCanvasLayer(nsDisplayListBuilder* aBuilder,
                              CanvasLayer *aOldLayer,
                              LayerManager *aManager)
@@ -861,28 +857,38 @@ WebGLContext::GetCanvasLayer(nsDisplayLi
       // The layer will be destroyed when we tear down the presentation
       // (at the latest), at which time this userData will be destroyed,
       // releasing the reference to the element.
       // The userData will receive DidTransactionCallbacks, which flush the
       // the invalidation state to indicate that the canvas is up to date.
       userData = new WebGLContextUserData(mCanvasElement);
       canvasLayer->SetDidTransactionCallback(
               WebGLContextUserData::DidTransactionCallback, userData);
-      canvasLayer->SetPreTransactionCallback(
-              WebGLContextUserData::PreTransactionCallback, userData);
     }
     canvasLayer->SetUserData(&gWebGLLayerUserData, userData);
 
     CanvasLayer::Data data;
-    data.mGLContext = gl;
+
+    // the gl context may either provide a native PBuffer, in which case we want to initialize
+    // data with the gl context directly, or may provide a surface to which it renders (this is the case
+    // of OSMesa contexts), in which case we want to initialize data with that surface.
+
+    void* native_surface = gl->GetNativeData(gl::GLContext::NativeImageSurface);
+
+    if (native_surface) {
+        data.mSurface = static_cast<gfxASurface*>(native_surface);
+    } else {
+        data.mGLContext = gl.get();
+    }
+
     data.mSize = nsIntSize(mWidth, mHeight);
-    data.mIsGLAlphaPremult = IsPremultAlpha();
+    data.mGLBufferIsPremultiplied = mOptions.premultipliedAlpha ? true : false;
 
     canvasLayer->Initialize(data);
-    uint32_t flags = gl->Caps().alpha ? 0 : Layer::CONTENT_OPAQUE;
+    uint32_t flags = gl->CreationFormat().alpha == 0 ? Layer::CONTENT_OPAQUE : 0;
     canvasLayer->SetContentFlags(flags);
     canvasLayer->Updated();
 
     mResetLayer = false;
 
     return canvasLayer.forget().get();
 }
 
@@ -890,22 +896,21 @@ void
 WebGLContext::GetContextAttributes(Nullable<dom::WebGLContextAttributesInitializer> &retval)
 {
     retval.SetNull();
     if (!IsContextStable())
         return;
 
     dom::WebGLContextAttributes& result = retval.SetValue();
 
-    const PixelBufferFormat& format = gl->GetPixelFormat();
-
-    result.mAlpha = format.alpha > 0;
-    result.mDepth = format.depth > 0;
-    result.mStencil = format.stencil > 0;
-    result.mAntialias = format.samples > 1;
+    gl::ContextFormat cf = gl->ActualFormat();
+    result.mAlpha = cf.alpha > 0;
+    result.mDepth = cf.depth > 0;
+    result.mStencil = cf.stencil > 0;
+    result.mAntialias = cf.samples > 1;
     result.mPremultipliedAlpha = mOptions.premultipliedAlpha;
     result.mPreserveDrawingBuffer = mOptions.preserveDrawingBuffer;
 }
 
 bool
 WebGLContext::IsExtensionEnabled(WebGLExtensionID ext) const {
     return mExtensions.SafeElementAt(ext);
 }
@@ -1099,128 +1104,50 @@ WebGLContext::GetExtension(JSContext *cx
         mExtensions.EnsureLengthAtLeast(ext + 1);
         mExtensions[ext] = obj;
     }
 
     return WebGLObjectAsJSObject(cx, mExtensions[ext].get(), rv);
 }
 
 void
-WebGLContext::ClearScreen()
-{
-    MakeContextCurrent();
-    ScopedBindFramebuffer autoFB(gl, 0);
-
-    GLbitfield clearMask = LOCAL_GL_COLOR_BUFFER_BIT;
-    if (mOptions.depth)
-        clearMask |= LOCAL_GL_DEPTH_BUFFER_BIT;
-    if (mOptions.stencil)
-        clearMask |= LOCAL_GL_STENCIL_BUFFER_BIT;
-
-    ForceClearFramebufferWithDefaultValues(clearMask);
-    mIsScreenCleared = true;
-}
-
-void
-WebGLContext::ForceClearFramebufferWithDefaultValues(GLbitfield mask)
+WebGLContext::ForceClearFramebufferWithDefaultValues(uint32_t mask, const nsIntRect& viewportRect)
 {
     MakeContextCurrent();
 
     bool initializeColorBuffer = 0 != (mask & LOCAL_GL_COLOR_BUFFER_BIT);
     bool initializeDepthBuffer = 0 != (mask & LOCAL_GL_DEPTH_BUFFER_BIT);
     bool initializeStencilBuffer = 0 != (mask & LOCAL_GL_STENCIL_BUFFER_BIT);
 
-    // Fun GL fact: No need to worry about the viewport here, glViewport is just
-    // setting up a coordinates transformation, it doesn't affect glClear at all.
-
-#ifdef DEBUG
-    // Scope to hide our variables.
-    {
-        // Sanity-check that all our state is set properly. Otherwise, when we
-        // reset out state to what we *think* it is, we'll get it wrong.
-
-        // Dither shouldn't matter when we're clearing to {0,0,0,0}.
-        MOZ_ASSERT(gl->fIsEnabled(LOCAL_GL_SCISSOR_TEST) == mScissorTestEnabled);
-
-        realGLboolean colorWriteMask[4] = {2, 2, 2, 2};
-        GLfloat colorClearValue[4] = {-1.0f, -1.0f, -1.0f, -1.0f};
-
-        gl->fGetBooleanv(LOCAL_GL_COLOR_WRITEMASK, colorWriteMask);
-        gl->fGetFloatv(LOCAL_GL_COLOR_CLEAR_VALUE, colorClearValue);
-
-        MOZ_ASSERT(colorWriteMask[0] == mColorWriteMask[0] &&
-                   colorWriteMask[1] == mColorWriteMask[1] &&
-                   colorWriteMask[2] == mColorWriteMask[2] &&
-                   colorWriteMask[3] == mColorWriteMask[3]);
-        MOZ_ASSERT(colorClearValue[0] == mColorClearValue[0] &&
-                   colorClearValue[1] == mColorClearValue[1] &&
-                   colorClearValue[2] == mColorClearValue[2] &&
-                   colorClearValue[3] == mColorClearValue[3]);
-
-
-        realGLboolean depthWriteMask = 2;
-        GLfloat depthClearValue = -1.0f;
+    // fun GL fact: no need to worry about the viewport here, glViewport is just setting up a coordinates transformation,
+    // it doesn't affect glClear at all
 
-        gl->fGetBooleanv(LOCAL_GL_DEPTH_WRITEMASK, &depthWriteMask);
-        gl->fGetFloatv(LOCAL_GL_DEPTH_CLEAR_VALUE, &depthClearValue);
-
-        MOZ_ASSERT(depthWriteMask  == mDepthWriteMask);
-        MOZ_ASSERT(depthClearValue == mDepthClearValue);
-
-
-        GLuint stencilWriteMaskFront = 0xdeadbad1;
-        GLuint stencilWriteMaskBack  = 0xdeadbad1;
-        GLuint stencilClearValue     = 0xdeadbad1;
-
-        gl->GetUIntegerv(LOCAL_GL_STENCIL_WRITEMASK,      &stencilWriteMaskFront);
-        gl->GetUIntegerv(LOCAL_GL_STENCIL_BACK_WRITEMASK, &stencilWriteMaskBack);
-        gl->GetUIntegerv(LOCAL_GL_STENCIL_CLEAR_VALUE,    &stencilClearValue);
-
-        GLuint stencilBits = 0;
-        gl->GetUIntegerv(LOCAL_GL_STENCIL_BITS, &stencilBits);
-        GLuint stencilMask = (GLuint(1) << stencilBits) - 1;
-
-        MOZ_ASSERT( ( stencilWriteMaskFront & stencilMask) ==
-                    (mStencilWriteMaskFront & stencilMask) );
-        MOZ_ASSERT( ( stencilWriteMaskBack & stencilMask) ==
-                    (mStencilWriteMaskBack & stencilMask) );
-        MOZ_ASSERT( ( stencilClearValue & stencilMask) ==
-                    (mStencilClearValue & stencilMask) );
-    }
-#endif
-
-    // Prepare GL state for clearing.
+    // prepare GL state for clearing
     gl->fDisable(LOCAL_GL_SCISSOR_TEST);
+    gl->fDisable(LOCAL_GL_DITHER);
 
     if (initializeColorBuffer) {
         gl->fColorMask(1, 1, 1, 1);
-        gl->fClearColor(0.0f, 0.0f, 0.0f, 0.0f);
+        gl->fClearColor(0.f, 0.f, 0.f, 0.f);
     }
 
     if (initializeDepthBuffer) {
         gl->fDepthMask(1);
         gl->fClearDepth(1.0f);
     }
 
     if (initializeStencilBuffer) {
-        // "The clear operation always uses the front stencil write mask
-        //  when clearing the stencil buffer."
-        gl->fStencilMaskSeparate(LOCAL_GL_FRONT, 0xffffffff);
-        gl->fStencilMaskSeparate(LOCAL_GL_BACK,  0xffffffff);
+        gl->fStencilMask(0xffffffff);
         gl->fClearStencil(0);
     }
 
-    // Do the clear!
+    // do clear
     gl->fClear(mask);
 
-    // And reset!
-    if (mScissorTestEnabled)
-        gl->fEnable(LOCAL_GL_SCISSOR_TEST);
-
-    // Restore GL state after clearing.
+    // restore GL state after clearing
     if (initializeColorBuffer) {
         gl->fColorMask(mColorWriteMask[0],
                        mColorWriteMask[1],
                        mColorWriteMask[2],
                        mColorWriteMask[3]);
         gl->fClearColor(mColorClearValue[0],
                         mColorClearValue[1],
                         mColorClearValue[2],
@@ -1229,43 +1156,51 @@ WebGLContext::ForceClearFramebufferWithD
 
     if (initializeDepthBuffer) {
         gl->fDepthMask(mDepthWriteMask);
         gl->fClearDepth(mDepthClearValue);
     }
 
     if (initializeStencilBuffer) {
         gl->fStencilMaskSeparate(LOCAL_GL_FRONT, mStencilWriteMaskFront);
-        gl->fStencilMaskSeparate(LOCAL_GL_BACK,  mStencilWriteMaskBack);
+        gl->fStencilMaskSeparate(LOCAL_GL_BACK, mStencilWriteMaskBack);
         gl->fClearStencil(mStencilClearValue);
     }
-}
-
-// For an overview of how WebGL compositing works, see:
-// https://wiki.mozilla.org/Platform/GFX/WebGL/Compositing
-bool
-WebGLContext::PresentScreenBuffer()
-{
-    if (!mShouldPresent) {
-        return false;
-    }
 
-    gl->MakeCurrent();
-    if (!gl->PublishFrame()) {
-        this->ForceLoseContext();
-        return false;
-    }
+    if (mDitherEnabled)
+        gl->fEnable(LOCAL_GL_DITHER);
+    else
+        gl->fDisable(LOCAL_GL_DITHER);
+
+    if (mScissorTestEnabled)
+        gl->fEnable(LOCAL_GL_SCISSOR_TEST);
+    else
+        gl->fDisable(LOCAL_GL_SCISSOR_TEST);
+}
 
-    if (!mOptions.preserveDrawingBuffer) {
-        ClearScreen();
-    }
+void
+WebGLContext::EnsureBackbufferClearedAsNeeded()
+{
+    if (mOptions.preserveDrawingBuffer)
+        return;
+
+    NS_ABORT_IF_FALSE(!mBoundFramebuffer,
+                      "EnsureBackbufferClearedAsNeeded must not be called when a FBO is bound");
 
-    mShouldPresent = false;
+    if (mBackbufferClearingStatus != BackbufferClearingStatus::NotClearedSinceLastPresented)
+        return;
+
+    mBackbufferClearingStatus = BackbufferClearingStatus::ClearedToDefaultValues;
 
-    return true;
+    ForceClearFramebufferWithDefaultValues(LOCAL_GL_COLOR_BUFFER_BIT |
+                                           LOCAL_GL_DEPTH_BUFFER_BIT |
+                                           LOCAL_GL_STENCIL_BUFFER_BIT,
+                                           nsIntRect(0, 0, mWidth, mHeight));
+
+    Invalidate();
 }
 
 void
 WebGLContext::DummyFramebufferOperation(const char *info)
 {
     WebGLenum status = CheckFramebufferStatus(LOCAL_GL_FRAMEBUFFER);
     if (status == LOCAL_GL_FRAMEBUFFER_COMPLETE)
         return;
--- a/content/canvas/src/WebGLContext.h
+++ b/content/canvas/src/WebGLContext.h
@@ -81,16 +81,20 @@ namespace dom {
 struct WebGLContextAttributes;
 struct WebGLContextAttributesInitializer;
 }
 
 struct VertexAttrib0Status {
     enum { Default, EmulatedUninitializedArray, EmulatedInitializedArray };
 };
 
+struct BackbufferClearingStatus {
+    enum { NotClearedSinceLastPresented, ClearedToDefaultValues, HasBeenDrawnTo };
+};
+
 namespace WebGLTexelConversions {
 
 /*
  * The formats that may participate, either as source or destination formats,
  * in WebGL texture conversions. This includes:
  *  - all the formats accepted by WebGL.texImage2D, e.g. RGBA4444
  *  - additional formats provided by extensions, e.g. RGB32F
  *  - additional source formats, depending on browser details, used when uploading
@@ -252,45 +256,33 @@ public:
     WebGLTexture *activeBoundTextureForTarget(WebGLenum target) {
         return target == LOCAL_GL_TEXTURE_2D ? mBound2DTextures[mActiveTexture]
                                              : mBoundCubeMapTextures[mActiveTexture];
     }
 
     already_AddRefed<CanvasLayer> GetCanvasLayer(nsDisplayListBuilder* aBuilder,
                                                  CanvasLayer *aOldLayer,
                                                  LayerManager *aManager);
-
-    // Note that 'clean' here refers to its invalidation state, not the
-    // contents of the buffer.
     void MarkContextClean() { mInvalidated = false; }
 
-    gl::GLContext* GL() const {
-        return gl;
-    }
-
-    bool IsPremultAlpha() const {
-        return mOptions.premultipliedAlpha;
-    }
-
-    bool PresentScreenBuffer();
-
     // a number that increments every time we have an event that causes
     // all context resources to be lost.
     uint32_t Generation() { return mGeneration.value(); }
 
     const WebGLRectangleObject *FramebufferRectangleObject() const;
 
-    // This is similar to GLContext::ClearSafely, but tries to minimize the
-    // amount of work it does.
-    // It only clears the buffers we specify, and can reset its state without
-    // first having to query anything, as WebGL knows its state at all times.
-    void ForceClearFramebufferWithDefaultValues(GLbitfield mask);
+    // this is similar to GLContext::ClearSafely, but is more comprehensive
+    // (takes care of scissor, stencil write mask, dithering, viewport...)
+    // WebGL has more complex needs than GLContext as content controls GL state.
+    void ForceClearFramebufferWithDefaultValues(uint32_t mask, const nsIntRect& viewportRect);
 
-    // Calls ForceClearFramebufferWithDefaultValues() for the Context's 'screen'.
-    void ClearScreen();
+    // if the preserveDrawingBuffer context option is false, we need to clear the back buffer
+    // after it's been presented to the compositor. This function does that if needed.
+    // See section 2.2 in the WebGL spec.
+    void EnsureBackbufferClearedAsNeeded();
 
     // checks for GL errors, clears any pending GL error, stores the current GL error in currentGLError,
     // and copies it into mWebGLError if it doesn't already have an error set
     void UpdateWebGLErrorAndClearGLError(GLenum *currentGLError) {
         // get and clear GL error in ALL cases
         *currentGLError = gl->GetAndClearError();
         // only store in mWebGLError if is hasn't already recorded an error
         if (!mWebGLError)
@@ -847,18 +839,16 @@ protected:
     bool mResetLayer;
     bool mOptionsFrozen;
     bool mMinCapability;
     bool mDisableExtensions;
     bool mHasRobustness;
     bool mIsMesa;
     bool mLoseContextOnHeapMinimize;
     bool mCanLoseContextInForeground;
-    bool mShouldPresent;
-    bool mIsScreenCleared;
 
     template<typename WebGLObjectType>
     void DeleteWebGLObjectsArray(nsTArray<WebGLObjectType>& array);
 
     WebGLuint mActiveTexture;
     WebGLenum mWebGLError;
 
     // whether shader validation is supported
@@ -1111,16 +1101,18 @@ protected:
     realGLboolean mColorWriteMask[4];
     realGLboolean mDepthWriteMask;
     realGLboolean mScissorTestEnabled;
     realGLboolean mDitherEnabled;
     WebGLfloat mColorClearValue[4];
     WebGLint mStencilClearValue;
     WebGLfloat mDepthClearValue;
 
+    int mBackbufferClearingStatus;
+
     nsCOMPtr<nsITimer> mContextRestorer;
     bool mAllowRestore;
     bool mContextLossTimerRunning;
     bool mDrawSinceContextLossTimerSet;
     ContextStatus mContextStatus;
     bool mContextLostErrorSet;
 
     int mAlreadyGeneratedWarnings;
--- a/content/canvas/src/WebGLContextGL.cpp
+++ b/content/canvas/src/WebGLContextGL.cpp
@@ -166,17 +166,17 @@ WebGLContext::BindFramebuffer(WebGLenum 
 
     // silently ignore a deleted frame buffer
     if (wfb && wfb->IsDeleted())
         return;
 
     MakeContextCurrent();
 
     if (!wfb) {
-        gl->fBindFramebuffer(target, 0);
+        gl->fBindFramebuffer(target, gl->GetOffscreenFBO());
     } else {
         WebGLuint framebuffername = wfb->GLName();
         gl->fBindFramebuffer(target, framebuffername);
         wfb->SetHasEverBeenBound(true);
     }
 
     mBoundFramebuffer = wfb;
 }
@@ -570,62 +570,42 @@ WebGLContext::Clear(WebGLbitfield mask)
         return;
 
     MakeContextCurrent();
 
     uint32_t m = mask & (LOCAL_GL_COLOR_BUFFER_BIT | LOCAL_GL_DEPTH_BUFFER_BIT | LOCAL_GL_STENCIL_BUFFER_BIT);
     if (mask != m)
         return ErrorInvalidValue("clear: invalid mask bits");
 
+    bool needClearCallHere = true;
+
     if (mBoundFramebuffer) {
         if (!mBoundFramebuffer->CheckAndInitializeRenderbuffers())
             return ErrorInvalidFramebufferOperation("clear: incomplete framebuffer");
-
-        gl->fClear(mask);
-        return;
-    }
-
-    // Ok, we're clearing the default framebuffer/screen.
-
-    bool needsClear = true;
-    if (mIsScreenCleared) {
-        bool isClearRedundant = true;
-        if (mask & LOCAL_GL_COLOR_BUFFER_BIT) {
-            if (mColorClearValue[0] != 0.0f ||
-                mColorClearValue[1] != 0.0f ||
-                mColorClearValue[2] != 0.0f ||
-                mColorClearValue[3] != 0.0f)
-            {
-                isClearRedundant = false;
-            }
+    } else {
+        // no FBO is bound, so we are clearing the backbuffer here
+        EnsureBackbufferClearedAsNeeded();
+        bool valuesAreDefault = mColorClearValue[0] == 0.0f &&
+                                  mColorClearValue[1] == 0.0f &&
+                                  mColorClearValue[2] == 0.0f &&
+                                  mColorClearValue[3] == 0.0f &&
+                                  mDepthClearValue    == 1.0f &&
+                                  mStencilClearValue  == 0;
+        if (valuesAreDefault &&
+            mBackbufferClearingStatus == BackbufferClearingStatus::ClearedToDefaultValues)
+        {
+            needClearCallHere = false;
         }
-
-        if (mask & LOCAL_GL_DEPTH_BUFFER_BIT) {
-            if (mDepthClearValue != 1.0f) {
-                isClearRedundant = false;
-            }
-        }
-
-        if (mask & LOCAL_GL_DEPTH_BUFFER_BIT) {
-            if (mStencilClearValue != 0) {
-                isClearRedundant = false;
-            }
-        }
-
-        if (isClearRedundant)
-            needsClear = false;
     }
 
-    if (needsClear) {
+    if (needClearCallHere) {
         gl->fClear(mask);
-        mIsScreenCleared = false;
+        mBackbufferClearingStatus = BackbufferClearingStatus::HasBeenDrawnTo;
+        Invalidate();
     }
-
-    Invalidate();
-    mShouldPresent = true;
 }
 
 void
 WebGLContext::ClearColor(WebGLclampf r, WebGLclampf g,
                          WebGLclampf b, WebGLclampf a)
 {
     if (!IsContextStable())
         return;
@@ -830,17 +810,17 @@ WebGLContext::CopyTexImage2D(WebGLenum t
               is_pot_assuming_nonnegative(height)))
             return ErrorInvalidValue("copyTexImage2D: with level > 0, width and height must be powers of two");
     }
 
     bool texFormatRequiresAlpha = internalformat == LOCAL_GL_RGBA ||
                                     internalformat == LOCAL_GL_ALPHA ||
                                     internalformat == LOCAL_GL_LUMINANCE_ALPHA;
     bool fboFormatHasAlpha = mBoundFramebuffer ? mBoundFramebuffer->ColorAttachment().HasAlpha()
-                                                 : bool(gl->GetPixelFormat().alpha > 0);
+                                                 : bool(gl->ActualFormat().alpha > 0);
     if (texFormatRequiresAlpha && !fboFormatHasAlpha)
         return ErrorInvalidOperation("copyTexImage2D: texture format requires an alpha channel "
                                      "but the framebuffer doesn't have one");
 
     if (internalformat == LOCAL_GL_DEPTH_COMPONENT ||
         internalformat == LOCAL_GL_DEPTH_STENCIL)
         return ErrorInvalidOperation("copyTexImage2D: a base internal format of DEPTH_COMPONENT or DEPTH_STENCIL isn't supported");
 
@@ -940,17 +920,17 @@ WebGLContext::CopyTexSubImage2D(WebGLenu
     if (yoffset + height > texHeight || yoffset + height < 0)
       return ErrorInvalidValue("copyTexSubImage2D: yoffset+height is too large");
 
     WebGLenum format = imageInfo.Format();
     bool texFormatRequiresAlpha = format == LOCAL_GL_RGBA ||
                                   format == LOCAL_GL_ALPHA ||
                                   format == LOCAL_GL_LUMINANCE_ALPHA;
     bool fboFormatHasAlpha = mBoundFramebuffer ? mBoundFramebuffer->ColorAttachment().HasAlpha()
-                                                 : bool(gl->GetPixelFormat().alpha > 0);
+                                                 : bool(gl->ActualFormat().alpha > 0);
 
     if (texFormatRequiresAlpha && !fboFormatHasAlpha)
         return ErrorInvalidOperation("copyTexSubImage2D: texture format requires an alpha channel "
                                      "but the framebuffer doesn't have one");
 
     if (format == LOCAL_GL_DEPTH_COMPONENT ||
         format == LOCAL_GL_DEPTH_STENCIL)
         return ErrorInvalidOperation("copyTexSubImage2D: a base internal format of DEPTH_COMPONENT or DEPTH_STENCIL isn't supported");
@@ -1455,33 +1435,32 @@ WebGLContext::DrawArrays(GLenum mode, We
     if (checked_firstPlusCount.value() > maxAllowedCount)
         return ErrorInvalidOperation("drawArrays: bound vertex attribute buffers do not have sufficient size for given first and count");
 
     MakeContextCurrent();
 
     if (mBoundFramebuffer) {
         if (!mBoundFramebuffer->CheckAndInitializeRenderbuffers())
             return ErrorInvalidFramebufferOperation("drawArrays: incomplete framebuffer");
+    } else {
+        EnsureBackbufferClearedAsNeeded();
     }
 
     BindFakeBlackTextures();
     if (!DoFakeVertexAttrib0(checked_firstPlusCount.value()))
         return;
 
     SetupContextLossTimer();
     gl->fDrawArrays(mode, first, count);
 
     UndoFakeVertexAttrib0();
     UnbindFakeBlackTextures();
 
-    if (!mBoundFramebuffer) {
-        Invalidate();
-        mShouldPresent = true;
-        mIsScreenCleared = false;
-    }
+    mBackbufferClearingStatus = BackbufferClearingStatus::HasBeenDrawnTo;
+    Invalidate();
 }
 
 void
 WebGLContext::DrawElements(WebGLenum mode, WebGLsizei count, WebGLenum type,
                            WebGLintptr byteOffset)
 {
     if (!IsContextStable())
         return;
@@ -1549,33 +1528,32 @@ WebGLContext::DrawElements(WebGLenum mod
             "size for given indices from the bound element array");
     }
 
     MakeContextCurrent();
 
     if (mBoundFramebuffer) {
         if (!mBoundFramebuffer->CheckAndInitializeRenderbuffers())
             return ErrorInvalidFramebufferOperation("drawElements: incomplete framebuffer");
+    } else {
+        EnsureBackbufferClearedAsNeeded();
     }
 
     BindFakeBlackTextures();
     if (!DoFakeVertexAttrib0(maxAllowedCount))
         return;
 
     SetupContextLossTimer();
     gl->fDrawElements(mode, count, type, reinterpret_cast<GLvoid*>(byteOffset));
 
     UndoFakeVertexAttrib0();
     UnbindFakeBlackTextures();
 
-    if (!mBoundFramebuffer) {
-        Invalidate();
-        mShouldPresent = true;
-        mIsScreenCleared = false;
-    }
+    mBackbufferClearingStatus = BackbufferClearingStatus::HasBeenDrawnTo;
+    Invalidate();
 }
 
 void
 WebGLContext::Enable(WebGLenum cap)
 {
     if (!IsContextStable())
         return;
 
@@ -3349,17 +3327,17 @@ WebGLContext::ReadPixels(WebGLint x, Web
     // GL_ALPHA to readpixels currently, but we had the code written for it already.
     if (format == LOCAL_GL_ALPHA ||
         format == LOCAL_GL_RGBA)
     {
         bool needAlphaFixup;
         if (mBoundFramebuffer) {
             needAlphaFixup = !mBoundFramebuffer->ColorAttachment().HasAlpha();
         } else {
-            needAlphaFixup = gl->GetPixelFormat().alpha == 0;
+            needAlphaFixup = gl->ActualFormat().alpha == 0;
         }
 
         if (needAlphaFixup) {
             if (format == LOCAL_GL_ALPHA && type == LOCAL_GL_UNSIGNED_BYTE) {
                 // this is easy; it's an 0xff memset per row
                 uint8_t *row = static_cast<uint8_t*>(data);
                 for (GLint j = 0; j < height; ++j) {
                     memset(row, 0xff, checked_plainRowSize.value());
--- a/content/canvas/src/WebGLFramebuffer.cpp
+++ b/content/canvas/src/WebGLFramebuffer.cpp
@@ -347,17 +347,17 @@ WebGLFramebuffer::CheckAndInitializeRend
     }
 
     if (mStencilAttachment.HasUninitializedRenderbuffer() ||
         mDepthStencilAttachment.HasUninitializedRenderbuffer())
     {
         mask |= LOCAL_GL_STENCIL_BUFFER_BIT;
     }
 
-    mContext->ForceClearFramebufferWithDefaultValues(mask);
+    mContext->ForceClearFramebufferWithDefaultValues(mask, nsIntRect(0, 0, rect->Width(), rect->Height()));
 
     if (mColorAttachment.HasUninitializedRenderbuffer())
         mColorAttachment.Renderbuffer()->SetInitialized(true);
 
     if (mDepthAttachment.HasUninitializedRenderbuffer())
         mDepthAttachment.Renderbuffer()->SetInitialized(true);
 
     if (mStencilAttachment.HasUninitializedRenderbuffer())
--- a/content/canvas/test/reftest/reftest.list
+++ b/content/canvas/test/reftest/reftest.list
@@ -6,192 +6,189 @@
 pref(webgl.disabled,true)  == webgl-disable-test.html       wrapper.html?green.png
 
 # Basic WebGL tests:
 # Do we get pixels to the screen at all?
 # Try to just hit the different rendering paths here.
 # Test: {aa, alpha, preserve, readback} = 16
 == webgl-clear-test.html?nogl  wrapper.html?green.png
 
-                      == webgl-clear-test.html?__&_____&________  wrapper.html?green.png
-                      == webgl-clear-test.html?aa&_____&________  wrapper.html?green.png
-fuzzy-if(B2G,256,83)  == webgl-clear-test.html?__&alpha&________  wrapper.html?green.png
-fuzzy-if(B2G,256,83)  == webgl-clear-test.html?aa&alpha&________  wrapper.html?green.png
-                      == webgl-clear-test.html?__&_____&preserve  wrapper.html?green.png
-                      == webgl-clear-test.html?aa&_____&preserve  wrapper.html?green.png
-fuzzy-if(B2G,256,83)  == webgl-clear-test.html?__&alpha&preserve  wrapper.html?green.png
-fuzzy-if(B2G,256,83)  == webgl-clear-test.html?aa&alpha&preserve  wrapper.html?green.png
+== webgl-clear-test.html?__&_____&________  wrapper.html?green.png
+== webgl-clear-test.html?aa&_____&________  wrapper.html?green.png
+== webgl-clear-test.html?__&alpha&________  wrapper.html?green.png
+== webgl-clear-test.html?aa&alpha&________  wrapper.html?green.png
+== webgl-clear-test.html?__&_____&preserve  wrapper.html?green.png
+== webgl-clear-test.html?aa&_____&preserve  wrapper.html?green.png
+== webgl-clear-test.html?__&alpha&preserve  wrapper.html?green.png
+== webgl-clear-test.html?aa&alpha&preserve  wrapper.html?green.png
 
-pref(webgl.force-layers-readback,true)                       == webgl-clear-test.html?readback&__&_____&________  wrapper.html?green.png
-pref(webgl.force-layers-readback,true)                       == webgl-clear-test.html?readback&aa&_____&________  wrapper.html?green.png
-pref(webgl.force-layers-readback,true) fuzzy-if(B2G,256,83)  == webgl-clear-test.html?readback&__&alpha&________  wrapper.html?green.png
-pref(webgl.force-layers-readback,true) fuzzy-if(B2G,256,83)  == webgl-clear-test.html?readback&aa&alpha&________  wrapper.html?green.png
-pref(webgl.force-layers-readback,true)                       == webgl-clear-test.html?readback&__&_____&preserve  wrapper.html?green.png
-pref(webgl.force-layers-readback,true)                       == webgl-clear-test.html?readback&aa&_____&preserve  wrapper.html?green.png
-pref(webgl.force-layers-readback,true) fuzzy-if(B2G,256,83)  == webgl-clear-test.html?readback&__&alpha&preserve  wrapper.html?green.png
-pref(webgl.force-layers-readback,true) fuzzy-if(B2G,256,83)  == webgl-clear-test.html?readback&aa&alpha&preserve  wrapper.html?green.png
+pref(webgl.force-layers-readback,true) fails-if(nativeFennec)  == webgl-clear-test.html?readback&__&_____&________  wrapper.html?green.png
+pref(webgl.force-layers-readback,true) fails-if(nativeFennec)  == webgl-clear-test.html?readback&aa&_____&________  wrapper.html?green.png
+pref(webgl.force-layers-readback,true)                         == webgl-clear-test.html?readback&__&alpha&________  wrapper.html?green.png
+pref(webgl.force-layers-readback,true)                         == webgl-clear-test.html?readback&aa&alpha&________  wrapper.html?green.png
+pref(webgl.force-layers-readback,true) fails-if(nativeFennec)  == webgl-clear-test.html?readback&__&_____&preserve  wrapper.html?green.png
+pref(webgl.force-layers-readback,true) fails-if(nativeFennec)  == webgl-clear-test.html?readback&aa&_____&preserve  wrapper.html?green.png
+pref(webgl.force-layers-readback,true)                         == webgl-clear-test.html?readback&__&alpha&preserve  wrapper.html?green.png
+pref(webgl.force-layers-readback,true)                         == webgl-clear-test.html?readback&aa&alpha&preserve  wrapper.html?green.png
 
 # Check orientation:
 == webgl-orientation-test.html?nogl  wrapper.html?white-top-left.png
 
-                      == webgl-orientation-test.html?__&_____&________  wrapper.html?white-top-left.png
-                      == webgl-orientation-test.html?aa&_____&________  wrapper.html?white-top-left.png
-fuzzy-if(B2G,256,83)  == webgl-orientation-test.html?__&alpha&________  wrapper.html?white-top-left.png
-fuzzy-if(B2G,256,83)  == webgl-orientation-test.html?aa&alpha&________  wrapper.html?white-top-left.png
-                      == webgl-orientation-test.html?__&_____&preserve  wrapper.html?white-top-left.png
-                      == webgl-orientation-test.html?aa&_____&preserve  wrapper.html?white-top-left.png
-fuzzy-if(B2G,256,83)  == webgl-orientation-test.html?__&alpha&preserve  wrapper.html?white-top-left.png
-fuzzy-if(B2G,256,83)  == webgl-orientation-test.html?aa&alpha&preserve  wrapper.html?white-top-left.png
+== webgl-orientation-test.html?__&_____&________  wrapper.html?white-top-left.png
+== webgl-orientation-test.html?aa&_____&________  wrapper.html?white-top-left.png
+== webgl-orientation-test.html?__&alpha&________  wrapper.html?white-top-left.png
+== webgl-orientation-test.html?aa&alpha&________  wrapper.html?white-top-left.png
+== webgl-orientation-test.html?__&_____&preserve  wrapper.html?white-top-left.png
+== webgl-orientation-test.html?aa&_____&preserve  wrapper.html?white-top-left.png
+== webgl-orientation-test.html?__&alpha&preserve  wrapper.html?white-top-left.png
+== webgl-orientation-test.html?aa&alpha&preserve  wrapper.html?white-top-left.png
 
-pref(webgl.force-layers-readback,true)                       == webgl-orientation-test.html?readback&__&_____&________  wrapper.html?white-top-left.png
-pref(webgl.force-layers-readback,true)                       == webgl-orientation-test.html?readback&aa&_____&________  wrapper.html?white-top-left.png
-pref(webgl.force-layers-readback,true) fuzzy-if(B2G,256,83)  == webgl-orientation-test.html?readback&__&alpha&________  wrapper.html?white-top-left.png
-pref(webgl.force-layers-readback,true) fuzzy-if(B2G,256,83)  == webgl-orientation-test.html?readback&aa&alpha&________  wrapper.html?white-top-left.png
-pref(webgl.force-layers-readback,true)                       == webgl-orientation-test.html?readback&__&_____&preserve  wrapper.html?white-top-left.png
-pref(webgl.force-layers-readback,true)                       == webgl-orientation-test.html?readback&aa&_____&preserve  wrapper.html?white-top-left.png
-pref(webgl.force-layers-readback,true) fuzzy-if(B2G,256,83)  == webgl-orientation-test.html?readback&__&alpha&preserve  wrapper.html?white-top-left.png
-pref(webgl.force-layers-readback,true) fuzzy-if(B2G,256,83)  == webgl-orientation-test.html?readback&aa&alpha&preserve  wrapper.html?white-top-left.png
+pref(webgl.force-layers-readback,true) fails-if(nativeFennec)  == webgl-orientation-test.html?readback&__&_____&________  wrapper.html?white-top-left.png
+pref(webgl.force-layers-readback,true) fails-if(nativeFennec)  == webgl-orientation-test.html?readback&aa&_____&________  wrapper.html?white-top-left.png
+pref(webgl.force-layers-readback,true)                         == webgl-orientation-test.html?readback&__&alpha&________  wrapper.html?white-top-left.png
+pref(webgl.force-layers-readback,true)                         == webgl-orientation-test.html?readback&aa&alpha&________  wrapper.html?white-top-left.png
+pref(webgl.force-layers-readback,true) fails-if(nativeFennec)  == webgl-orientation-test.html?readback&__&_____&preserve  wrapper.html?white-top-left.png
+pref(webgl.force-layers-readback,true) fails-if(nativeFennec)  == webgl-orientation-test.html?readback&aa&_____&preserve  wrapper.html?white-top-left.png
+pref(webgl.force-layers-readback,true)                         == webgl-orientation-test.html?readback&__&alpha&preserve  wrapper.html?white-top-left.png
+pref(webgl.force-layers-readback,true)                         == webgl-orientation-test.html?readback&aa&alpha&preserve  wrapper.html?white-top-left.png
 
 # Does we draw the correct color in the correct places with all context creation options?
 # (Note that our context creation option matrix is 2^6 = 64)
 == webgl-color-test.html?nogl  wrapper.html?colors.png
 
-                      == webgl-color-test.html?__&_____&_____&_______&________&_______  wrapper.html?colors.png
-                      == webgl-color-test.html?aa&_____&_____&_______&________&_______  wrapper.html?colors.png
-fuzzy-if(B2G,256,83)  == webgl-color-test.html?__&alpha&_____&_______&________&_______  wrapper.html?colors.png
-fuzzy-if(B2G,256,83)  == webgl-color-test.html?aa&alpha&_____&_______&________&_______  wrapper.html?colors.png
-                      == webgl-color-test.html?__&_____&depth&_______&________&_______  wrapper.html?colors.png
-                      == webgl-color-test.html?aa&_____&depth&_______&________&_______  wrapper.html?colors.png
-fuzzy-if(B2G,256,83)  == webgl-color-test.html?__&alpha&depth&_______&________&_______  wrapper.html?colors.png
-fuzzy-if(B2G,256,83)  == webgl-color-test.html?aa&alpha&depth&_______&________&_______  wrapper.html?colors.png
-                      == webgl-color-test.html?__&_____&_____&premult&________&_______  wrapper.html?colors.png
-                      == webgl-color-test.html?aa&_____&_____&premult&________&_______  wrapper.html?colors.png
-fuzzy-if(B2G,256,83)  == webgl-color-test.html?__&alpha&_____&premult&________&_______  wrapper.html?colors.png
-fuzzy-if(B2G,256,83)  == webgl-color-test.html?aa&alpha&_____&premult&________&_______  wrapper.html?colors.png
-                      == webgl-color-test.html?__&_____&depth&premult&________&_______  wrapper.html?colors.png
-                      == webgl-color-test.html?aa&_____&depth&premult&________&_______  wrapper.html?colors.png
-fuzzy-if(B2G,256,83)  == webgl-color-test.html?__&alpha&depth&premult&________&_______  wrapper.html?colors.png
-fuzzy-if(B2G,256,83)  == webgl-color-test.html?aa&alpha&depth&premult&________&_______  wrapper.html?colors.png
+== webgl-color-test.html?__&_____&_____&_______&________&_______  wrapper.html?colors.png
+== webgl-color-test.html?aa&_____&_____&_______&________&_______  wrapper.html?colors.png
+== webgl-color-test.html?__&alpha&_____&_______&________&_______  wrapper.html?colors.png
+== webgl-color-test.html?aa&alpha&_____&_______&________&_______  wrapper.html?colors.png
+== webgl-color-test.html?__&_____&depth&_______&________&_______  wrapper.html?colors.png
+== webgl-color-test.html?aa&_____&depth&_______&________&_______  wrapper.html?colors.png
+== webgl-color-test.html?__&alpha&depth&_______&________&_______  wrapper.html?colors.png
+== webgl-color-test.html?aa&alpha&depth&_______&________&_______  wrapper.html?colors.png
+== webgl-color-test.html?__&_____&_____&premult&________&_______  wrapper.html?colors.png
+== webgl-color-test.html?aa&_____&_____&premult&________&_______  wrapper.html?colors.png
+== webgl-color-test.html?__&alpha&_____&premult&________&_______  wrapper.html?colors.png
+== webgl-color-test.html?aa&alpha&_____&premult&________&_______  wrapper.html?colors.png
+== webgl-color-test.html?__&_____&depth&premult&________&_______  wrapper.html?colors.png
+== webgl-color-test.html?aa&_____&depth&premult&________&_______  wrapper.html?colors.png
+== webgl-color-test.html?__&alpha&depth&premult&________&_______  wrapper.html?colors.png
+== webgl-color-test.html?aa&alpha&depth&premult&________&_______  wrapper.html?colors.png
 
-                      == webgl-color-test.html?__&_____&_____&_______&preserve&_______  wrapper.html?colors.png
-                      == webgl-color-test.html?aa&_____&_____&_______&preserve&_______  wrapper.html?colors.png
-fuzzy-if(B2G,256,83)  == webgl-color-test.html?__&alpha&_____&_______&preserve&_______  wrapper.html?colors.png
-fuzzy-if(B2G,256,83)  == webgl-color-test.html?aa&alpha&_____&_______&preserve&_______  wrapper.html?colors.png
-                      == webgl-color-test.html?__&_____&depth&_______&preserve&_______  wrapper.html?colors.png
-                      == webgl-color-test.html?aa&_____&depth&_______&preserve&_______  wrapper.html?colors.png
-fuzzy-if(B2G,256,83)  == webgl-color-test.html?__&alpha&depth&_______&preserve&_______  wrapper.html?colors.png
-fuzzy-if(B2G,256,83)  == webgl-color-test.html?aa&alpha&depth&_______&preserve&_______  wrapper.html?colors.png
-                      == webgl-color-test.html?__&_____&_____&premult&preserve&_______  wrapper.html?colors.png
-                      == webgl-color-test.html?aa&_____&_____&premult&preserve&_______  wrapper.html?colors.png
-fuzzy-if(B2G,256,83)  == webgl-color-test.html?__&alpha&_____&premult&preserve&_______  wrapper.html?colors.png
-fuzzy-if(B2G,256,83)  == webgl-color-test.html?aa&alpha&_____&premult&preserve&_______  wrapper.html?colors.png
-                      == webgl-color-test.html?__&_____&depth&premult&preserve&_______  wrapper.html?colors.png
-                      == webgl-color-test.html?aa&_____&depth&premult&preserve&_______  wrapper.html?colors.png
-fails-if(B2G)         == webgl-color-test.html?__&alpha&depth&premult&preserve&_______  wrapper.html?colors.png
-fails-if(B2G)         == webgl-color-test.html?aa&alpha&depth&premult&preserve&_______  wrapper.html?colors.png
+== webgl-color-test.html?__&_____&_____&_______&preserve&_______  wrapper.html?colors.png
+== webgl-color-test.html?aa&_____&_____&_______&preserve&_______  wrapper.html?colors.png
+== webgl-color-test.html?__&alpha&_____&_______&preserve&_______  wrapper.html?colors.png
+== webgl-color-test.html?aa&alpha&_____&_______&preserve&_______  wrapper.html?colors.png
+== webgl-color-test.html?__&_____&depth&_______&preserve&_______  wrapper.html?colors.png
+== webgl-color-test.html?aa&_____&depth&_______&preserve&_______  wrapper.html?colors.png
+== webgl-color-test.html?__&alpha&depth&_______&preserve&_______  wrapper.html?colors.png
+== webgl-color-test.html?aa&alpha&depth&_______&preserve&_______  wrapper.html?colors.png
+== webgl-color-test.html?__&_____&_____&premult&preserve&_______  wrapper.html?colors.png
+== webgl-color-test.html?aa&_____&_____&premult&preserve&_______  wrapper.html?colors.png
+== webgl-color-test.html?__&alpha&_____&premult&preserve&_______  wrapper.html?colors.png
+== webgl-color-test.html?aa&alpha&_____&premult&preserve&_______  wrapper.html?colors.png
+== webgl-color-test.html?__&_____&depth&premult&preserve&_______  wrapper.html?colors.png
+== webgl-color-test.html?aa&_____&depth&premult&preserve&_______  wrapper.html?colors.png
+== webgl-color-test.html?__&alpha&depth&premult&preserve&_______  wrapper.html?colors.png
+== webgl-color-test.html?aa&alpha&depth&premult&preserve&_______  wrapper.html?colors.png
 
-                      == webgl-color-test.html?__&_____&_____&_______&________&stencil  wrapper.html?colors.png
-                      == webgl-color-test.html?aa&_____&_____&_______&________&stencil  wrapper.html?colors.png
-fuzzy-if(B2G,256,83)  == webgl-color-test.html?__&alpha&_____&_______&________&stencil  wrapper.html?colors.png
-fails-if(B2G)         == webgl-color-test.html?aa&alpha&_____&_______&________&stencil  wrapper.html?colors.png
-                      == webgl-color-test.html?__&_____&depth&_______&________&stencil  wrapper.html?colors.png
-                      == webgl-color-test.html?aa&_____&depth&_______&________&stencil  wrapper.html?colors.png
-fuzzy-if(B2G,256,83)  == webgl-color-test.html?__&alpha&depth&_______&________&stencil  wrapper.html?colors.png
-fuzzy-if(B2G,256,83)  == webgl-color-test.html?aa&alpha&depth&_______&________&stencil  wrapper.html?colors.png
-                      == webgl-color-test.html?__&_____&_____&premult&________&stencil  wrapper.html?colors.png
-                      == webgl-color-test.html?aa&_____&_____&premult&________&stencil  wrapper.html?colors.png
-fuzzy-if(B2G,256,83)  == webgl-color-test.html?__&alpha&_____&premult&________&stencil  wrapper.html?colors.png
-fuzzy-if(B2G,256,83)  == webgl-color-test.html?aa&alpha&_____&premult&________&stencil  wrapper.html?colors.png
-                      == webgl-color-test.html?__&_____&depth&premult&________&stencil  wrapper.html?colors.png
-                      == webgl-color-test.html?aa&_____&depth&premult&________&stencil  wrapper.html?colors.png
-fuzzy-if(B2G,256,83)  == webgl-color-test.html?__&alpha&depth&premult&________&stencil  wrapper.html?colors.png
-fuzzy-if(B2G,256,83)  == webgl-color-test.html?aa&alpha&depth&premult&________&stencil  wrapper.html?colors.png
+== webgl-color-test.html?__&_____&_____&_______&________&stencil  wrapper.html?colors.png
+== webgl-color-test.html?aa&_____&_____&_______&________&stencil  wrapper.html?colors.png
+== webgl-color-test.html?__&alpha&_____&_______&________&stencil  wrapper.html?colors.png
+== webgl-color-test.html?aa&alpha&_____&_______&________&stencil  wrapper.html?colors.png
+== webgl-color-test.html?__&_____&depth&_______&________&stencil  wrapper.html?colors.png
+== webgl-color-test.html?aa&_____&depth&_______&________&stencil  wrapper.html?colors.png
+== webgl-color-test.html?__&alpha&depth&_______&________&stencil  wrapper.html?colors.png
+== webgl-color-test.html?aa&alpha&depth&_______&________&stencil  wrapper.html?colors.png
+== webgl-color-test.html?__&_____&_____&premult&________&stencil  wrapper.html?colors.png
+== webgl-color-test.html?aa&_____&_____&premult&________&stencil  wrapper.html?colors.png
+== webgl-color-test.html?__&alpha&_____&premult&________&stencil  wrapper.html?colors.png
+== webgl-color-test.html?aa&alpha&_____&premult&________&stencil  wrapper.html?colors.png
+== webgl-color-test.html?__&_____&depth&premult&________&stencil  wrapper.html?colors.png
+== webgl-color-test.html?aa&_____&depth&premult&________&stencil  wrapper.html?colors.png
+== webgl-color-test.html?__&alpha&depth&premult&________&stencil  wrapper.html?colors.png
+== webgl-color-test.html?aa&alpha&depth&premult&________&stencil  wrapper.html?colors.png
 
-                      == webgl-color-test.html?__&_____&_____&_______&preserve&stencil  wrapper.html?colors.png
-                      == webgl-color-test.html?aa&_____&_____&_______&preserve&stencil  wrapper.html?colors.png
-fuzzy-if(B2G,256,83)  == webgl-color-test.html?__&alpha&_____&_______&preserve&stencil  wrapper.html?colors.png
-fuzzy-if(B2G,256,83)  == webgl-color-test.html?aa&alpha&_____&_______&preserve&stencil  wrapper.html?colors.png
-                      == webgl-color-test.html?__&_____&depth&_______&preserve&stencil  wrapper.html?colors.png
-                      == webgl-color-test.html?aa&_____&depth&_______&preserve&stencil  wrapper.html?colors.png
-fuzzy-if(B2G,256,83)  == webgl-color-test.html?__&alpha&depth&_______&preserve&stencil  wrapper.html?colors.png
-fuzzy-if(B2G,256,83)  == webgl-color-test.html?aa&alpha&depth&_______&preserve&stencil  wrapper.html?colors.png
-                      == webgl-color-test.html?__&_____&_____&premult&preserve&stencil  wrapper.html?colors.png
-                      == webgl-color-test.html?aa&_____&_____&premult&preserve&stencil  wrapper.html?colors.png
-fuzzy-if(B2G,256,83)  == webgl-color-test.html?__&alpha&_____&premult&preserve&stencil  wrapper.html?colors.png
-fuzzy-if(B2G,256,83)  == webgl-color-test.html?aa&alpha&_____&premult&preserve&stencil  wrapper.html?colors.png
-                      == webgl-color-test.html?__&_____&depth&premult&preserve&stencil  wrapper.html?colors.png
-                      == webgl-color-test.html?aa&_____&depth&premult&preserve&stencil  wrapper.html?colors.png
-fuzzy-if(B2G,256,83)  == webgl-color-test.html?__&alpha&depth&premult&preserve&stencil  wrapper.html?colors.png
-fuzzy-if(B2G,256,83)  == webgl-color-test.html?aa&alpha&depth&premult&preserve&stencil  wrapper.html?colors.png
+== webgl-color-test.html?__&_____&_____&_______&preserve&stencil  wrapper.html?colors.png
+== webgl-color-test.html?aa&_____&_____&_______&preserve&stencil  wrapper.html?colors.png
+== webgl-color-test.html?__&alpha&_____&_______&preserve&stencil  wrapper.html?colors.png
+== webgl-color-test.html?aa&alpha&_____&_______&preserve&stencil  wrapper.html?colors.png
+== webgl-color-test.html?__&_____&depth&_______&preserve&stencil  wrapper.html?colors.png
+== webgl-color-test.html?aa&_____&depth&_______&preserve&stencil  wrapper.html?colors.png
+== webgl-color-test.html?__&alpha&depth&_______&preserve&stencil  wrapper.html?colors.png
+== webgl-color-test.html?aa&alpha&depth&_______&preserve&stencil  wrapper.html?colors.png
+== webgl-color-test.html?__&_____&_____&premult&preserve&stencil  wrapper.html?colors.png
+== webgl-color-test.html?aa&_____&_____&premult&preserve&stencil  wrapper.html?colors.png
+== webgl-color-test.html?__&alpha&_____&premult&preserve&stencil  wrapper.html?colors.png
+== webgl-color-test.html?aa&alpha&_____&premult&preserve&stencil  wrapper.html?colors.png
+== webgl-color-test.html?__&_____&depth&premult&preserve&stencil  wrapper.html?colors.png
+== webgl-color-test.html?aa&_____&depth&premult&preserve&stencil  wrapper.html?colors.png
+== webgl-color-test.html?__&alpha&depth&premult&preserve&stencil  wrapper.html?colors.png
+== webgl-color-test.html?aa&alpha&depth&premult&preserve&stencil  wrapper.html?colors.png
 
 
 # Check a smaller selection for readback:
-pref(webgl.force-layers-readback,true)                       == webgl-color-test.html?readback&__&_____&________  wrapper.html?colors.png
-pref(webgl.force-layers-readback,true)                       == webgl-color-test.html?readback&aa&_____&________  wrapper.html?colors.png
-pref(webgl.force-layers-readback,true) fuzzy-if(B2G,256,83)  == webgl-color-test.html?readback&__&alpha&________  wrapper.html?colors.png
-pref(webgl.force-layers-readback,true) fuzzy-if(B2G,256,83)  == webgl-color-test.html?readback&aa&alpha&________  wrapper.html?colors.png
-pref(webgl.force-layers-readback,true)                       == webgl-color-test.html?readback&__&_____&preserve  wrapper.html?colors.png
-pref(webgl.force-layers-readback,true)                       == webgl-color-test.html?readback&aa&_____&preserve  wrapper.html?colors.png
-pref(webgl.force-layers-readback,true) fuzzy-if(B2G,256,83)  == webgl-color-test.html?readback&__&alpha&preserve  wrapper.html?colors.png
-pref(webgl.force-layers-readback,true) fuzzy-if(B2G,256,83)  == webgl-color-test.html?readback&aa&alpha&preserve  wrapper.html?colors.png
+pref(webgl.force-layers-readback,true) fails-if(nativeFennec)  == webgl-color-test.html?readback&__&_____&________  wrapper.html?colors.png
+pref(webgl.force-layers-readback,true) fails-if(nativeFennec)  == webgl-color-test.html?readback&aa&_____&________  wrapper.html?colors.png
+pref(webgl.force-layers-readback,true)                         == webgl-color-test.html?readback&__&alpha&________  wrapper.html?colors.png
+pref(webgl.force-layers-readback,true)                         == webgl-color-test.html?readback&aa&alpha&________  wrapper.html?colors.png
+pref(webgl.force-layers-readback,true) fails-if(nativeFennec)  == webgl-color-test.html?readback&__&_____&preserve  wrapper.html?colors.png
+pref(webgl.force-layers-readback,true) fails-if(nativeFennec)  == webgl-color-test.html?readback&aa&_____&preserve  wrapper.html?colors.png
+pref(webgl.force-layers-readback,true)                         == webgl-color-test.html?readback&__&alpha&preserve  wrapper.html?colors.png
+pref(webgl.force-layers-readback,true)                         == webgl-color-test.html?readback&aa&alpha&preserve  wrapper.html?colors.png
 
 
 # Check alpha behavior:
-fuzzy-if(B2G,256,83)  == webgl-color-alpha-test.html?colorVal=1.0&alphaVal=1.0&nogl        wrapper.html?colors.png
-fuzzy-if(B2G,256,83)  == webgl-color-alpha-test.html?colorVal=1.0&alphaVal=1.0             wrapper.html?colors.png
-fuzzy-if(B2G,256,83)  == webgl-color-alpha-test.html?colorVal=0.0&alphaVal=1.0&nogl        wrapper.html?black.png
-fuzzy-if(B2G,256,83)  == webgl-color-alpha-test.html?colorVal=0.0&alphaVal=1.0             wrapper.html?black.png
+== webgl-color-alpha-test.html?colorVal=1.0&alphaVal=1.0&nogl        wrapper.html?colors.png
+== webgl-color-alpha-test.html?colorVal=1.0&alphaVal=1.0             wrapper.html?colors.png
+== webgl-color-alpha-test.html?colorVal=0.0&alphaVal=1.0&nogl        wrapper.html?black.png
+== webgl-color-alpha-test.html?colorVal=0.0&alphaVal=1.0             wrapper.html?black.png
 
-fuzzy-if(B2G,256,83)  == webgl-color-alpha-test.html?colorVal=1.0&alphaVal=0.0&nogl        wrapper.html?colors.png
-fuzzy-if(B2G,256,83)  == webgl-color-alpha-test.html?colorVal=1.0&alphaVal=0.0             wrapper.html?colors.png
-fuzzy-if(B2G,256,83)  == webgl-color-alpha-test.html?colorVal=1.0&alphaVal=0.0&alpha&nogl  wrapper.html?white.png
-fails-if(B2G)         == webgl-color-alpha-test.html?colorVal=1.0&alphaVal=0.0&alpha       wrapper.html?white.png
+== webgl-color-alpha-test.html?colorVal=1.0&alphaVal=0.0&nogl        wrapper.html?colors.png
+== webgl-color-alpha-test.html?colorVal=1.0&alphaVal=0.0             wrapper.html?colors.png
+== webgl-color-alpha-test.html?colorVal=1.0&alphaVal=0.0&alpha&nogl  wrapper.html?white.png
+== webgl-color-alpha-test.html?colorVal=1.0&alphaVal=0.0&alpha       wrapper.html?white.png
 
-fuzzy(1,65536) fuzzy-if(B2G,256,83) fuzzy-if(Android||B2G,9,65536)  == webgl-color-alpha-test.html?colorVal=0.5&alphaVal=1.0&nogl  wrapper.html?half-colors.png
-fuzzy(1,65536) fuzzy-if(B2G,256,83) fuzzy-if(Android||B2G,9,65536)  == webgl-color-alpha-test.html?colorVal=0.5&alphaVal=1.0       wrapper.html?half-colors.png
+fuzzy(1,65536) fuzzy-if(Android||B2G,9,65536) == webgl-color-alpha-test.html?colorVal=0.5&alphaVal=1.0&nogl  wrapper.html?half-colors.png
+fuzzy(1,65536) fuzzy-if(Android||B2G,9,65536) == webgl-color-alpha-test.html?colorVal=0.5&alphaVal=1.0       wrapper.html?half-colors.png
 
 # Test premult:
-fuzzy(1,65536) fuzzy-if(B2G,256,83) fuzzy-if(Android||B2G,9,65536)                                 == webgl-color-alpha-test.html?colorVal=1.0&alphaVal=0.5&alpha&nogl          wrapper.html?colors-half-alpha.png
-fuzzy(1,65536) fails-if(B2G)        fuzzy-if(Android,9,65536)                                      == webgl-color-alpha-test.html?colorVal=1.0&alphaVal=0.5&alpha               wrapper.html?colors-half-alpha.png
-fuzzy(1,65536) fuzzy-if(B2G,256,83) fuzzy-if(Android||B2G,9,65536)                                 == webgl-color-alpha-test.html?colorVal=0.5&alphaVal=0.5&alpha&nogl          wrapper.html?half-colors-half-alpha.png
-fuzzy(1,65536) fails-if(B2G)        fuzzy-if(Android,9,65536) fails-if(cocoaWidget||Android)       == webgl-color-alpha-test.html?colorVal=0.5&alphaVal=0.5&alpha               wrapper.html?half-colors-half-alpha.png
-fuzzy(1,65536) fuzzy-if(B2G,256,83) fuzzy-if(Android||B2G,9,65536)                                 == webgl-color-alpha-test.html?colorVal=0.5&alphaVal=0.5&alpha&premult&nogl  wrapper.html?colors-half-alpha.png
-fuzzy(1,65536) fails-if(B2G)        fuzzy-if(Android,9,65536)                                      == webgl-color-alpha-test.html?colorVal=0.5&alphaVal=0.5&alpha&premult       wrapper.html?colors-half-alpha.png
+fuzzy(1,65536) fuzzy-if(Android||B2G,9,65536)                                == webgl-color-alpha-test.html?colorVal=1.0&alphaVal=0.5&alpha&nogl          wrapper.html?colors-half-alpha.png
+fuzzy(1,65536) fuzzy-if(Android||B2G,9,65536)                                == webgl-color-alpha-test.html?colorVal=1.0&alphaVal=0.5&alpha               wrapper.html?colors-half-alpha.png
+fuzzy(1,65536) fuzzy-if(Android||B2G,9,65536)                                == webgl-color-alpha-test.html?colorVal=0.5&alphaVal=0.5&alpha&nogl          wrapper.html?half-colors-half-alpha.png
+fuzzy(1,65536) fuzzy-if(Android||B2G,9,65536) fails-if(cocoaWidget||Android) == webgl-color-alpha-test.html?colorVal=0.5&alphaVal=0.5&alpha               wrapper.html?half-colors-half-alpha.png
+fuzzy(1,65536) fuzzy-if(Android||B2G,9,65536)                                == webgl-color-alpha-test.html?colorVal=0.5&alphaVal=0.5&alpha&premult&nogl  wrapper.html?colors-half-alpha.png
+fuzzy(1,65536) fuzzy-if(Android||B2G,9,65536)                                == webgl-color-alpha-test.html?colorVal=0.5&alphaVal=0.5&alpha&premult       wrapper.html?colors-half-alpha.png
 
 # Test over-bright premult:
-fuzzy(1,65536) fuzzy-if(B2G,256,83) fuzzy-if(Android||B2G,9,65536)  == webgl-color-alpha-test.html?colorVal=1.0&alphaVal=0.5&alpha&premult&nogl  wrapper.html?colors-half-alpha.png
-fuzzy(1,65536) fails-if(B2G)        fuzzy-if(Android,9,65536)       == webgl-color-alpha-test.html?colorVal=1.0&alphaVal=0.5&alpha&premult       wrapper.html?colors-half-alpha.png
+fuzzy(1,65536) fuzzy-if(Android||B2G,9,65536) == webgl-color-alpha-test.html?colorVal=1.0&alphaVal=0.5&alpha&premult&nogl  wrapper.html?colors-half-alpha.png
+fuzzy(1,65536) fuzzy-if(Android||B2G,9,65536) == webgl-color-alpha-test.html?colorVal=1.0&alphaVal=0.5&alpha&premult       wrapper.html?colors-half-alpha.png
 
 
 # Check for hanging framebuffer bindings:
 == webgl-hanging-fb-test.html?nogl  wrapper.html?green.png
 
-                                        == webgl-hanging-fb-test.html?__&________  wrapper.html?green.png
-                                        == webgl-hanging-fb-test.html?aa&________  wrapper.html?green.png
-pref(webgl.force-layers-readback,true)  == webgl-hanging-fb-test.html?__&readback  wrapper.html?green.png
-pref(webgl.force-layers-readback,true)  == webgl-hanging-fb-test.html?aa&readback  wrapper.html?green.png
+== webgl-hanging-fb-test.html       wrapper.html?green.png
+== webgl-hanging-fb-test.html?aa    wrapper.html?green.png
+pref(webgl.force-layers-readback,true) fails-if(nativeFennec)  == webgl-hanging-fb-test.html?readback     wrapper.html?green.png
+pref(webgl.force-layers-readback,true) fails-if(nativeFennec)  == webgl-hanging-fb-test.html?readback&aa  wrapper.html?green.png
 
-                                        == webgl-hanging-scissor-test.html?__&________  wrapper.html?green.png
-                                        == webgl-hanging-scissor-test.html?aa&________  wrapper.html?green.png
-pref(webgl.force-layers-readback,true)  == webgl-hanging-scissor-test.html?__&readback  wrapper.html?green.png
-pref(webgl.force-layers-readback,true)  == webgl-hanging-scissor-test.html?aa&readback  wrapper.html?green.png
+== webgl-hanging-scissor-test.html       wrapper.html?green.png
+== webgl-hanging-scissor-test.html?aa    wrapper.html?green.png
+pref(webgl.force-layers-readback,true) fails-if(nativeFennec)  == webgl-hanging-scissor-test.html?readback     wrapper.html?green.png
+pref(webgl.force-layers-readback,true) fails-if(nativeFennec)  == webgl-hanging-scissor-test.html?readback&aa  wrapper.html?green.png
 
 
 # Check that our experimental prefs still work:
 
 # 16bpp:
-skip-if(winWidget) pref(webgl.prefer-16bpp,true)                                         == webgl-color-test.html?16bpp           wrapper.html?colors.png
-skip-if(winWidget) pref(webgl.prefer-16bpp,true) pref(webgl.force-layers-readback,true)  == webgl-color-test.html?16bpp&readback  wrapper.html?colors.png
+pref(webgl.prefer-16bpp,true)                                                               == webgl-color-test.html?16bpp           wrapper.html?colors.png
+pref(webgl.prefer-16bpp,true) pref(webgl.force-layers-readback,true) fails-if(nativeFennec) == webgl-color-test.html?16bpp&readback  wrapper.html?colors.png
 
 # Force native GL (Windows):
 skip-if(!winWidget) pref(webgl.prefer-native-gl,true)                                == webgl-clear-test.html?native-gl        wrapper.html?green.png
 skip-if(!winWidget) pref(webgl.prefer-native-gl,true)                                == webgl-orientation-test.html?native-gl  wrapper.html?white-top-left.png
 skip-if(!winWidget) pref(webgl.prefer-native-gl,true)                                == webgl-color-test.html?native-gl        wrapper.html?colors.png
 skip-if(!winWidget) pref(webgl.prefer-native-gl,true) pref(webgl.prefer-16bpp,true)  == webgl-color-test.html?native-gl&16bpp  wrapper.html?colors.png
 
-
-# Non-WebGL Reftests!
-
 # Do we correctly handle multiple clip paths?
 != clip-multiple-paths.html clip-multiple-paths-badref.html
 
 # Bug 815648
 == stroketext-shadow.html stroketext-shadow-ref.html
--- a/dom/bindings/test/test_integers.html
+++ b/dom/bindings/test/test_integers.html
@@ -18,23 +18,17 @@
     // ints edge cases.
     try {
       var gl = $("c").getContext("experimental-webgl");
     } catch (ex) {
       // No WebGL support on MacOS 10.5.  Just skip this test
       todo(false, "WebGL not supported");
       return;
     }
-    var error = gl.getError()
-
-    // on the b2g emulator we get GL_INVALID_FRAMEBUFFER_OPERATION
-    if (error == 0x0506) // GL_INVALID_FRAMEBUFFER_OPERATION
-        return;
-
-    is(error, 0, "Should not start in an error state");
+    is(gl.getError(), 0, "Should not start in an error state");
 
     var b = gl.createBuffer();
     gl.bindBuffer(gl.ARRAY_BUFFER, b);
 
     var a = new Float32Array(1);
     gl.bufferData(gl.ARRAY_BUFFER, a, gl.STATIC_DRAW);
 
     gl.bufferSubData(gl.ARRAY_BUFFER, arg, a);
--- a/dom/plugins/base/nsNPAPIPluginInstance.cpp
+++ b/dom/plugins/base/nsNPAPIPluginInstance.cpp
@@ -77,19 +77,17 @@ private:
   bool mCanceled;
 };
 
 static nsRefPtr<GLContext> sPluginContext = nullptr;
 
 static bool EnsureGLContext()
 {
   if (!sPluginContext) {
-    gfxIntSize dummySize(16, 16);
-    GLContext::SurfaceCaps dummyCaps;
-    sPluginContext = GLContextProvider::CreateOffscreen(dummySize, dummyCaps);
+    sPluginContext = GLContextProvider::CreateOffscreen(gfxIntSize(16, 16));
   }
 
   return sPluginContext != nullptr;
 }
 
 class SharedPluginTexture {
 public:
   NS_INLINE_DECL_REFCOUNTING(SharedPluginTexture)
--- a/gfx/gl/GLContext.cpp
+++ b/gfx/gl/GLContext.cpp
@@ -2,43 +2,50 @@
 /* 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 <algorithm>
 #include <stdio.h>
 #include <string.h>
 
+#include "mozilla/DebugOnly.h"
+
+#include "prlink.h"
+#include "prenv.h"
+
+#include "nsThreadUtils.h"
+
+#include "gfxPlatform.h"
 #include "GLContext.h"
+#include "GLContextProvider.h"
 
 #include "gfxCrashReporterUtils.h"
-#include "gfxPlatform.h"
 #include "gfxUtils.h"
-#include "GLContextProvider.h"
+
+#include "mozilla/Preferences.h"
+
 #include "GLTextureImage.h"
+
 #include "nsIMemoryReporter.h"
-#include "nsThreadUtils.h"
-#include "prenv.h"
-#include "prlink.h"
-#include "SurfaceStream.h"
-
-#include "mozilla/DebugOnly.h"
-#include "mozilla/Preferences.h"
 
 using namespace mozilla::gfx;
 
 namespace mozilla {
 namespace gl {
 
 #ifdef DEBUG
 unsigned GLContext::sCurrentGLContextTLS = -1;
 #endif
 
 uint32_t GLContext::sDebugMode = 0;
 
+// define this here since it's global to GLContextProvider, not any
+// specific implementation
+const ContextFormat ContextFormat::BasicRGBA32Format(ContextFormat::BasicRGBA32);
 
 #define MAX_SYMBOL_LENGTH 128
 #define MAX_SYMBOL_NAMES 5
 
 // should match the order of GLExtensions, and be null-terminated.
 static const char *sExtensionNames[] = {
     "GL_EXT_framebuffer_object",
     "GL_ARB_framebuffer_object",
@@ -300,66 +307,58 @@ GLContext::InitWithPrefix(const char *pr
 
             if (!LoadSymbols(&symbols_desktop[0], trygl, prefix)) {
                 NS_ERROR("Desktop symbols failed to load.");
                 mInitialized = false;
             }
         }
     }
 
-    const char *glVendorString = nullptr;
-    const char *glRendererString = nullptr;
+    const char *glVendorString;
+    const char *glRendererString;
 
     if (mInitialized) {
         // The order of these strings must match up with the order of the enum
         // defined in GLContext.h for vendor IDs
         glVendorString = (const char *)fGetString(LOCAL_GL_VENDOR);
-        if (!glVendorString)
-            mInitialized = false;
-
         const char *vendorMatchStrings[VendorOther] = {
                 "Intel",
                 "NVIDIA",
                 "ATI",
                 "Qualcomm",
                 "Imagination",
                 "nouveau"
         };
-
         mVendor = VendorOther;
         for (int i = 0; i < VendorOther; ++i) {
             if (DoesStringMatch(glVendorString, vendorMatchStrings[i])) {
                 mVendor = i;
                 break;
             }
         }
 
         // The order of these strings must match up with the order of the enum
         // defined in GLContext.h for renderer IDs
         glRendererString = (const char *)fGetString(LOCAL_GL_RENDERER);
-        if (!glRendererString)
-            mInitialized = false;
-
         const char *rendererMatchStrings[RendererOther] = {
                 "Adreno 200",
                 "Adreno 205",
                 "PowerVR SGX 530",
-                "PowerVR SGX 540"
+                "PowerVR SGX 540",
+
         };
-
         mRenderer = RendererOther;
         for (int i = 0; i < RendererOther; ++i) {
             if (DoesStringMatch(glRendererString, rendererMatchStrings[i])) {
                 mRenderer = i;
                 break;
             }
         }
     }
 
-
 #ifdef DEBUG
     if (PR_GetEnv("MOZ_GL_DEBUG"))
         sDebugMode |= DebugEnabled;
 
     // enables extra verbose output, informing of the start and finish of every GL call.
     // useful e.g. to record information to investigate graphics system crashes/lockups
     if (PR_GetEnv("MOZ_GL_DEBUG_VERBOSE"))
         sDebugMode |= DebugTrace;
@@ -375,17 +374,16 @@ GLContext::InitWithPrefix(const char *pr
         if (firstRun && DebugMode()) {
             const char *vendors[VendorOther] = {
                 "Intel",
                 "NVIDIA",
                 "ATI",
                 "Qualcomm"
             };
 
-            MOZ_ASSERT(glVendorString);
             if (mVendor < VendorOther) {
                 printf_stderr("OpenGL vendor ('%s') recognized as: %s\n",
                               glVendorString, vendors[mVendor]);
             } else {
                 printf_stderr("OpenGL vendor ('%s') unrecognized\n", glVendorString);
             }
         }
         firstRun = false;
@@ -451,19 +449,20 @@ GLContext::InitWithPrefix(const char *pr
                 NS_ERROR("GL supports framebuffer_blit without supplying glBlitFramebuffer");
 
                 MarkExtensionUnsupported(ANGLE_framebuffer_blit);
                 MarkExtensionUnsupported(EXT_framebuffer_blit);
                 mSymbols.fBlitFramebuffer = nullptr;
             }
         }
 
-        if (SupportsFramebufferMultisample())
+        if (SupportsOffscreenSplit() &&
+            ( IsExtensionSupported(GLContext::ANGLE_framebuffer_multisample) ||
+              IsExtensionSupported(GLContext::EXT_framebuffer_multisample) ))
         {
-            MOZ_ASSERT(SupportsSplitFramebuffer());
             SymLoadStruct auxSymbols[] = {
                 {
                     (PRFuncPtr*) &mSymbols.fRenderbufferStorageMultisample,
                     {
                         "RenderbufferStorageMultisample",
                         "RenderbufferStorageMultisampleEXT",
                         "RenderbufferStorageMultisampleANGLE",
                         nullptr
@@ -504,26 +503,24 @@ GLContext::InitWithPrefix(const char *pr
                 mSymbols.fGetInteger64v = nullptr;
                 mSymbols.fGetSynciv = nullptr;
             }
         }
 
         if (IsExtensionSupported(OES_EGL_image)) {
             SymLoadStruct imageSymbols[] = {
                 { (PRFuncPtr*) &mSymbols.fEGLImageTargetTexture2D, { "EGLImageTargetTexture2DOES", nullptr } },
-                { (PRFuncPtr*) &mSymbols.fEGLImageTargetRenderbufferStorage, { "EGLImageTargetRenderbufferStorageOES", nullptr } },
                 { nullptr, { nullptr } },
             };
 
             if (!LoadSymbols(&imageSymbols[0], trygl, prefix)) {
                 NS_ERROR("GL supports OES_EGL_image without supplying its functions.");
 
                 MarkExtensionUnsupported(OES_EGL_image);
                 mSymbols.fEGLImageTargetTexture2D = nullptr;
-                mSymbols.fEGLImageTargetRenderbufferStorage = nullptr;
             }
         }
        
         // Load developer symbols, don't fail if we can't find them.
         SymLoadStruct auxSymbols[] = {
                 { (PRFuncPtr*) &mSymbols.fGetTexImage, { "GetTexImage", nullptr } },
                 { (PRFuncPtr*) &mSymbols.fGetTexLevelParameteriv, { "GetTexLevelParameteriv", nullptr } },
                 { nullptr, { nullptr } },
@@ -562,33 +559,17 @@ GLContext::InitWithPrefix(const char *pr
             // see bug 814716. Clamp MaxCubeMapTextureSize at 2K for Nouveau.
             mMaxCubeMapTextureSize = std::min(mMaxCubeMapTextureSize, 2048);
             mNeedsTextureSizeChecks = true;
         }
 #endif
 
         mMaxTextureImageSize = mMaxTextureSize;
 
-        mMaxSamples = 0;
-        if (SupportsFramebufferMultisample()) {
-            fGetIntegerv(LOCAL_GL_MAX_SAMPLES, (GLint*)&mMaxSamples);
-        }
-
-        // We're ready for final setup.
-        InitFramebuffers();
-
-        if (mCaps.any)
-            DetermineCaps();
-
-        UpdatePixelFormat();
-        UpdateGLFormats(mCaps);
-
-        mTexGarbageBin = new TextureGarbageBin(this);
-
-        MOZ_ASSERT(IsCurrent());
+        UpdateActualFormat();
     }
 
     if (mInitialized)
         reporter.SetSuccessful();
     else {
         // if initialization fails, ensure all symbols are zero, to avoid hard-to-understand bugs
         mSymbols.Zero();
         NS_WARNING("InitWithPrefix failed!");
@@ -836,182 +817,148 @@ void GLContext::ApplyFilterToBoundTextur
         fTexParameteri(aTarget, LOCAL_GL_TEXTURE_MAG_FILTER, LOCAL_GL_NEAREST);
     } else {
         fTexParameteri(aTarget, LOCAL_GL_TEXTURE_MIN_FILTER, LOCAL_GL_LINEAR);
         fTexParameteri(aTarget, LOCAL_GL_TEXTURE_MAG_FILTER, LOCAL_GL_LINEAR);
     }
 }
 
 
-void
-GLContext::DetermineCaps()
-{
-    PixelBufferFormat format = QueryPixelFormat();
-
-    SurfaceCaps caps;
-    caps.color = !!format.red && !!format.green && !!format.blue;
-    caps.bpp16 = caps.color && format.ColorBits() == 16;
-    caps.alpha = !!format.alpha;
-    caps.depth = !!format.depth;
-    caps.stencil = !!format.stencil;
-    caps.antialias = format.samples > 1;
-    caps.preserve = true;
-
-    mCaps = caps;
-}
-
-PixelBufferFormat
-GLContext::QueryPixelFormat()
-{
-    PixelBufferFormat format;
-
-    ScopedBindFramebuffer autoFB(this, 0);
-
-    fGetIntegerv(LOCAL_GL_RED_BITS  , &format.red  );
-    fGetIntegerv(LOCAL_GL_GREEN_BITS, &format.green);
-    fGetIntegerv(LOCAL_GL_BLUE_BITS , &format.blue );
-    fGetIntegerv(LOCAL_GL_ALPHA_BITS, &format.alpha);
-
-    fGetIntegerv(LOCAL_GL_DEPTH_BITS, &format.depth);
-    fGetIntegerv(LOCAL_GL_STENCIL_BITS, &format.stencil);
-
-    fGetIntegerv(LOCAL_GL_SAMPLES, &format.samples);
-
-    return format;
-}
-
-void
-GLContext::UpdatePixelFormat()
-{
-    PixelBufferFormat format = QueryPixelFormat();
-#ifdef DEBUG
-    const SurfaceCaps& caps = Caps();
-    MOZ_ASSERT(caps.color == !!format.red);
-    MOZ_ASSERT(caps.color == !!format.green);
-    MOZ_ASSERT(caps.color == !!format.blue);
-    MOZ_ASSERT(caps.alpha == !!format.alpha);
-    MOZ_ASSERT(caps.depth == !!format.depth);
-    MOZ_ASSERT(caps.stencil == !!format.stencil);
-    MOZ_ASSERT(caps.antialias == (format.samples > 1));
-#endif
-    mPixelFormat = new PixelBufferFormat(format);
-}
-
-GLFormats
-GLContext::ChooseGLFormats(const SurfaceCaps& caps) const
+GLContext::GLFormats
+GLContext::ChooseGLFormats(ContextFormat& aCF, ColorByteOrder aByteOrder)
 {
     GLFormats formats;
 
     // If we're on ES2 hardware and we have an explicit request for 16 bits of color or less
     // OR we don't support full 8-bit color, return a 4444 or 565 format.
-    bool bpp16 = caps.bpp16;
-    if (mIsGLES2) {
-        if (!IsExtensionSupported(OES_rgb8_rgba8))
-            bpp16 = true;
+    if (mIsGLES2 && (aCF.colorBits() <= 16 || !IsExtensionSupported(OES_rgb8_rgba8))) {
+        if (aCF.alpha) {
+            formats.texColor = LOCAL_GL_RGBA;
+            formats.texColorType = LOCAL_GL_UNSIGNED_SHORT_4_4_4_4;
+            formats.rbColor = LOCAL_GL_RGBA4;
+
+            aCF.red = aCF.green = aCF.blue = aCF.alpha = 4;
+        } else {
+            formats.texColor = LOCAL_GL_RGB;
+            formats.texColorType = LOCAL_GL_UNSIGNED_SHORT_5_6_5;
+            formats.rbColor = LOCAL_GL_RGB565;
+
+            aCF.red = 5;
+            aCF.green = 6;
+            aCF.blue = 5;
+            aCF.alpha = 0;
+        }   
     } else {
-        // RGB565 is uncommon on desktop, requiring ARB_ES2_compatibility.
-        // Since it's also vanishingly useless there, let's not support it.
-        bpp16 = false;
-    }
+        formats.texColorType = LOCAL_GL_UNSIGNED_BYTE;
 
-    if (bpp16) {
-        MOZ_ASSERT(mIsGLES2);
-        if (caps.alpha) {
-            formats.color_texInternalFormat = LOCAL_GL_RGBA;
-            formats.color_texFormat = LOCAL_GL_RGBA;
-            formats.color_texType   = LOCAL_GL_UNSIGNED_SHORT_4_4_4_4;
-            formats.color_rbFormat  = LOCAL_GL_RGBA4;
+        if (aCF.alpha) {
+            // Prefer BGRA8888 on ES2 hardware; if the extension is supported, it
+            // should be faster.  There are some cases where we don't want this --
+            // specifically, CopyTex*Image doesn't seem to understand how to deal
+            // with a BGRA source going to a RGB/RGBA destination on some drivers.
+            if (mIsGLES2 &&
+                IsExtensionSupported(EXT_texture_format_BGRA8888) &&
+                aByteOrder != ForceRGBA)
+            {
+                formats.texColor = LOCAL_GL_BGRA;
+            } else {
+                formats.texColor = LOCAL_GL_RGBA;
+            }
+
+            formats.rbColor = LOCAL_GL_RGBA8;
+
+            aCF.red = aCF.green = aCF.blue = aCF.alpha = 8;
         } else {
-            formats.color_texInternalFormat = LOCAL_GL_RGB;
-            formats.color_texFormat = LOCAL_GL_RGB;
-            formats.color_texType   = LOCAL_GL_UNSIGNED_SHORT_5_6_5;
-            formats.color_rbFormat  = LOCAL_GL_RGB565;
-        }
-    } else {
-        formats.color_texType = LOCAL_GL_UNSIGNED_BYTE;
+            formats.texColor = LOCAL_GL_RGB;
+            formats.rbColor = LOCAL_GL_RGB8;
 
-        if (caps.alpha) {
-            formats.color_texInternalFormat = mIsGLES2 ? LOCAL_GL_RGBA : LOCAL_GL_RGBA8;
-            formats.color_texFormat = LOCAL_GL_RGBA;
-            formats.color_rbFormat  = LOCAL_GL_RGBA8;
-        } else {
-            formats.color_texInternalFormat = mIsGLES2 ? LOCAL_GL_RGB : LOCAL_GL_RGB8;
-            formats.color_texFormat = LOCAL_GL_RGB;
-            formats.color_rbFormat  = LOCAL_GL_RGB8;
+            aCF.red = aCF.green = aCF.blue = 8;
+            aCF.alpha = 0;
         }
     }
 
-    uint32_t msaaLevel = Preferences::GetUint("gl.msaa-level", 2);
-    GLsizei samples = msaaLevel * msaaLevel;
-    samples = std::min(samples, mMaxSamples);
+    GLsizei samples = aCF.samples;
 
-    // Bug 778765.
+    GLsizei maxSamples = 0;
+    if (SupportsFramebufferMultisample())
+        fGetIntegerv(LOCAL_GL_MAX_SAMPLES, (GLint*)&maxSamples);
+    samples = std::min(samples, maxSamples);
+
+    // bug 778765
     if (WorkAroundDriverBugs() && samples == 1) {
         samples = 0;
     }
+
     formats.samples = samples;
+    aCF.samples = samples;
 
 
-    // Be clear that these are 0 if unavailable.
+    const int depth = aCF.depth;
+    const int stencil = aCF.stencil;
+    const bool useDepthStencil =
+        !mIsGLES2 || IsExtensionSupported(OES_packed_depth_stencil);
+
     formats.depthStencil = 0;
-    if (!mIsGLES2 || IsExtensionSupported(OES_packed_depth_stencil)) {
-        formats.depthStencil = LOCAL_GL_DEPTH24_STENCIL8;
-    }
-
     formats.depth = 0;
-    if (mIsGLES2) {
-        if (IsExtensionSupported(OES_depth24)) {
-            formats.depth = LOCAL_GL_DEPTH_COMPONENT24;
-        } else {
-            formats.depth = LOCAL_GL_DEPTH_COMPONENT16;
+    formats.stencil = 0;
+    if (depth && stencil && useDepthStencil) {
+        formats.depthStencil = LOCAL_GL_DEPTH24_STENCIL8;
+        aCF.depth = 24;
+        aCF.stencil = 8;
+    } else {
+        if (depth) {
+            if (mIsGLES2) {
+                if (IsExtensionSupported(OES_depth24)) {
+                    formats.depth = LOCAL_GL_DEPTH_COMPONENT24;
+                    aCF.depth = 24;
+                } else {
+                    formats.depth = LOCAL_GL_DEPTH_COMPONENT16;
+                    aCF.depth = 16;
+                }
+            } else {
+                formats.depth = LOCAL_GL_DEPTH_COMPONENT24;
+                aCF.depth = 24;
+            }
         }
-    } else {
-        formats.depth = LOCAL_GL_DEPTH_COMPONENT24;
+
+        if (stencil) {
+            formats.stencil = LOCAL_GL_STENCIL_INDEX8;
+            aCF.stencil = 8;
+        }
     }
 
-    formats.stencil = LOCAL_GL_STENCIL_INDEX8;
-
     return formats;
 }
 
-GLuint
-GLContext::CreateTextureForOffscreen(const GLFormats& formats, const gfxIntSize& size)
+void
+GLContext::CreateTextureForOffscreen(const GLFormats& aFormats, const gfxIntSize& aSize, GLuint& texture)
 {
-    MOZ_ASSERT(formats.color_texInternalFormat);
-    MOZ_ASSERT(formats.color_texFormat);
-    MOZ_ASSERT(formats.color_texType);
+    GLuint boundTexture = 0;
+    fGetIntegerv(LOCAL_GL_TEXTURE_BINDING_2D, (GLint*)&boundTexture);
 
-    return CreateTexture(formats.color_texInternalFormat,
-                         formats.color_texFormat,
-                         formats.color_texType,
-                         size);
-}
+    if (texture == 0) {
+        fGenTextures(1, &texture);
+    }
 
-GLuint
-GLContext::CreateTexture(GLenum internalFormat, GLenum format, GLenum type, const gfxIntSize& size)
-{
-    GLuint tex = 0;
-    fGenTextures(1, &tex);
-    ScopedBindTexture autoTex(this, tex);
-
+    fBindTexture(LOCAL_GL_TEXTURE_2D, texture);
     fTexParameteri(LOCAL_GL_TEXTURE_2D, LOCAL_GL_TEXTURE_MIN_FILTER, LOCAL_GL_LINEAR);
     fTexParameteri(LOCAL_GL_TEXTURE_2D, LOCAL_GL_TEXTURE_MAG_FILTER, LOCAL_GL_LINEAR);
     fTexParameteri(LOCAL_GL_TEXTURE_2D, LOCAL_GL_TEXTURE_WRAP_S, LOCAL_GL_CLAMP_TO_EDGE);
     fTexParameteri(LOCAL_GL_TEXTURE_2D, LOCAL_GL_TEXTURE_WRAP_T, LOCAL_GL_CLAMP_TO_EDGE);
 
     fTexImage2D(LOCAL_GL_TEXTURE_2D,
                 0,
-                internalFormat,
-                size.width, size.height,
+                aFormats.texColor,
+                aSize.width, aSize.height,
                 0,
-                format,
-                type,
+                aFormats.texColor,
+                aFormats.texColorType,
                 nullptr);
 
-    return tex;
+    fBindTexture(LOCAL_GL_TEXTURE_2D, boundTexture);
 }
 
 static inline void
 RenderbufferStorageBySamples(GLContext* gl, GLsizei samples, GLenum internalFormat, const gfxIntSize& size)
 {
     if (samples) {
         gl->fRenderbufferStorageMultisample(LOCAL_GL_RENDERBUFFER,
                                             samples,
@@ -1019,167 +966,100 @@ RenderbufferStorageBySamples(GLContext* 
                                             size.width, size.height);
     } else {
         gl->fRenderbufferStorage(LOCAL_GL_RENDERBUFFER,
                                  internalFormat,
                                  size.width, size.height);
     }
 }
 
-GLuint
-GLContext::CreateRenderbuffer(GLenum format, GLsizei samples, const gfxIntSize& size)
+void
+GLContext::CreateRenderbuffersForOffscreen(const GLContext::GLFormats& aFormats, const gfxIntSize& aSize,
+                                           GLuint& colorMSRB, GLuint& depthRB, GLuint& stencilRB)
 {
-    GLuint rb = 0;
-    fGenRenderbuffers(1, &rb);
-    ScopedBindRenderbuffer autoRB(this, rb);
+    GLuint boundRB = 0;
+    fGetIntegerv(LOCAL_GL_RENDERBUFFER_BINDING, (GLint*)&boundRB);
 
-    RenderbufferStorageBySamples(this, samples, format, size);
-
-    return rb;
-}
 
-void
-GLContext::CreateRenderbuffersForOffscreen(const GLFormats& formats, const gfxIntSize& size,
-                                           bool multisample,
-                                           GLuint* colorMSRB, GLuint* depthRB, GLuint* stencilRB)
-{
-    GLsizei samples = multisample ? formats.samples : 0;
-    if (colorMSRB) {
-        MOZ_ASSERT(formats.samples > 0);
-        MOZ_ASSERT(formats.color_rbFormat);
+    colorMSRB = 0;
+    depthRB = 0;
+    stencilRB = 0;
 
-        *colorMSRB = CreateRenderbuffer(formats.color_rbFormat, samples, size);
+    if (aFormats.samples > 0) {
+        fGenRenderbuffers(1, &colorMSRB);
+        fBindRenderbuffer(LOCAL_GL_RENDERBUFFER, colorMSRB);
+        RenderbufferStorageBySamples(this, aFormats.samples, aFormats.rbColor, aSize);
     }
 
-    if (depthRB &&
-        stencilRB &&
-        formats.depthStencil)
-    {
-        *depthRB = CreateRenderbuffer(formats.depthStencil, samples, size);
-        *stencilRB = *depthRB;
-    } else {
-        if (depthRB) {
-            MOZ_ASSERT(formats.depth);
+    // If depthStencil, disallow depth, stencil
+    MOZ_ASSERT(!aFormats.depthStencil || (!aFormats.depth && !aFormats.stencil));
+
+    if (aFormats.depthStencil) {
+        fGenRenderbuffers(1, &depthRB);
+        stencilRB = depthRB;
+        fBindRenderbuffer(LOCAL_GL_RENDERBUFFER, depthRB);
+        RenderbufferStorageBySamples(this, aFormats.samples, aFormats.depthStencil, aSize);
+    }
 
-            *depthRB = CreateRenderbuffer(formats.depth, samples, size);
-        }
+    if (aFormats.depth) {
+        fGenRenderbuffers(1, &depthRB);
+        fBindRenderbuffer(LOCAL_GL_RENDERBUFFER, depthRB);
+        RenderbufferStorageBySamples(this, aFormats.samples, aFormats.depth, aSize);
+    }
 
-        if (stencilRB) {
-            MOZ_ASSERT(formats.stencil);
+    if (aFormats.stencil) {
+        fGenRenderbuffers(1, &stencilRB);
+        fBindRenderbuffer(LOCAL_GL_RENDERBUFFER, stencilRB);
+        RenderbufferStorageBySamples(this, aFormats.samples, aFormats.stencil, aSize);
+    }
 
-            *stencilRB = CreateRenderbuffer(formats.stencil, samples, size);
-        }
-    }
+
+    fBindRenderbuffer(LOCAL_GL_RENDERBUFFER, boundRB);
 }
 
 bool
-GLContext::IsFramebufferComplete(GLuint fb, GLenum* pStatus)
+GLContext::AssembleOffscreenFBOs(const GLuint colorMSRB,
+                                 const GLuint depthRB,
+                                 const GLuint stencilRB,
+                                 const GLuint texture,
+                                 GLuint& drawFBO,
+                                 GLuint& readFBO)
 {
-    MOZ_ASSERT(fb);
-
-    ScopedBindFramebuffer autoFB(this, fb);
-    MOZ_ASSERT(fIsFramebuffer(fb));
-
-    GLenum status = fCheckFramebufferStatus(LOCAL_GL_FRAMEBUFFER);
-    if (pStatus)
-        *pStatus = status;
-
-    return status == LOCAL_GL_FRAMEBUFFER_COMPLETE;
-}
-
-void
-GLContext::AttachBuffersToFB(GLuint colorTex, GLuint colorRB,
-                             GLuint depthRB, GLuint stencilRB,
-                             GLuint fb)
-{
-    MOZ_ASSERT(fb);
-    MOZ_ASSERT( !(colorTex && colorRB) );
-
-    ScopedBindFramebuffer autoFB(this, fb);
-    MOZ_ASSERT(fIsFramebuffer(fb)); // It only counts after being bound.
+    drawFBO = 0;
+    readFBO = 0;
 
-    if (colorTex) {
-        MOZ_ASSERT(fIsTexture(colorTex));
-        fFramebufferTexture2D(LOCAL_GL_FRAMEBUFFER,
-                              LOCAL_GL_COLOR_ATTACHMENT0,
-                              LOCAL_GL_TEXTURE_2D,
-                              colorTex,
-                              0);
-    } else if (colorRB) {
-        MOZ_ASSERT(fIsRenderbuffer(colorRB));
-        fFramebufferRenderbuffer(LOCAL_GL_FRAMEBUFFER,
-                                 LOCAL_GL_COLOR_ATTACHMENT0,
-                                 LOCAL_GL_RENDERBUFFER,
-                                 colorRB);
-    }
-
-    if (depthRB) {
-        MOZ_ASSERT(fIsRenderbuffer(depthRB));
-        fFramebufferRenderbuffer(LOCAL_GL_FRAMEBUFFER,
-                                 LOCAL_GL_DEPTH_ATTACHMENT,
-                                 LOCAL_GL_RENDERBUFFER,
-                                 depthRB);
-    }
-
-    if (stencilRB) {
-        MOZ_ASSERT(fIsRenderbuffer(stencilRB));
-        fFramebufferRenderbuffer(LOCAL_GL_FRAMEBUFFER,
-                                 LOCAL_GL_STENCIL_ATTACHMENT,
-                                 LOCAL_GL_RENDERBUFFER,
-                                 stencilRB);
-    }
-}
-
-bool
-GLContext::AssembleOffscreenFBs(const GLuint colorMSRB,
-                                const GLuint depthRB,
-                                const GLuint stencilRB,
-                                const GLuint texture,
-                                GLuint* drawFB_out,
-                                GLuint* readFB_out)
-{
     if (!colorMSRB && !texture) {
         MOZ_ASSERT(!depthRB && !stencilRB);
-
-        if (drawFB_out)
-            *drawFB_out = 0;
-        if (readFB_out)
-            *readFB_out = 0;
-
         return true;
     }
 
-    ScopedBindFramebuffer autoFB(this);
-
-    GLuint drawFB = 0;
-    GLuint readFB = 0;
+    GLuint boundDrawFBO = GetUserBoundDrawFBO();
+    GLuint boundReadFBO = GetUserBoundReadFBO();
 
     if (texture) {
-        readFB = 0;
-        fGenFramebuffers(1, &readFB);
-        BindFB(readFB);
+        fGenFramebuffers(1, &readFBO);
+        BindInternalFBO(readFBO);
         fFramebufferTexture2D(LOCAL_GL_FRAMEBUFFER,
                               LOCAL_GL_COLOR_ATTACHMENT0,
                               LOCAL_GL_TEXTURE_2D,
                               texture,
                               0);
     }
 
     if (colorMSRB) {
-        drawFB = 0;
-        fGenFramebuffers(1, &drawFB);
-        BindFB(drawFB);
+        fGenFramebuffers(1, &drawFBO);
+        BindInternalFBO(drawFBO);
         fFramebufferRenderbuffer(LOCAL_GL_FRAMEBUFFER,
                                  LOCAL_GL_COLOR_ATTACHMENT0,
                                  LOCAL_GL_RENDERBUFFER,
                                  colorMSRB);
     } else {
-        drawFB = readFB;
+        drawFBO = readFBO;
+        // drawFBO==readFBO is already bound from the 'if (texture)' block.
     }
-    MOZ_ASSERT(GetFB() == drawFB);
 
     if (depthRB) {
         fFramebufferRenderbuffer(LOCAL_GL_FRAMEBUFFER,
                                  LOCAL_GL_DEPTH_ATTACHMENT,
                                  LOCAL_GL_RENDERBUFFER,
                                  depthRB);
     }
 
@@ -1189,74 +1069,142 @@ GLContext::AssembleOffscreenFBs(const GL
                                  LOCAL_GL_RENDERBUFFER,
                                  stencilRB);
     }
 
     // We should be all resized.  Check for framebuffer completeness.
     GLenum status;
     bool isComplete = true;
 
-    if (!IsFramebufferComplete(drawFB, &status)) {
+    BindInternalFBO(drawFBO);
+    status = fCheckFramebufferStatus(LOCAL_GL_FRAMEBUFFER);
+    if (status != LOCAL_GL_FRAMEBUFFER_COMPLETE) {
         NS_WARNING("DrawFBO: Incomplete");
   #ifdef DEBUG
         if (DebugMode()) {
             printf_stderr("Framebuffer status: %X\n", status);
         }
   #endif
         isComplete = false;
     }
 
-    if (!IsFramebufferComplete(readFB, &status)) {
+    BindInternalFBO(readFBO);
+    status = fCheckFramebufferStatus(LOCAL_GL_FRAMEBUFFER);
+    if (status != LOCAL_GL_FRAMEBUFFER_COMPLETE) {
         NS_WARNING("ReadFBO: Incomplete");
   #ifdef DEBUG
         if (DebugMode()) {
             printf_stderr("Framebuffer status: %X\n", status);
         }
   #endif
         isComplete = false;
     }
 
-    if (drawFB_out) {
-        *drawFB_out = drawFB;
-    } else if (drawFB) {
-        NS_RUNTIMEABORT("drawFB created when not requested!");
-    }
-
-    if (readFB_out) {
-        *readFB_out = readFB;
-    } else if (readFB) {
-        NS_RUNTIMEABORT("readFB created when not requested!");
-    }
+    BindUserDrawFBO(boundDrawFBO);
+    BindUserReadFBO(boundReadFBO);
 
     return isComplete;
 }
 
-
-
 bool
-GLContext::PublishFrame()
+GLContext::ResizeOffscreenFBOs(const ContextFormat& aCF, const gfxIntSize& aSize, const bool aNeedsReadBuffer)
 {
-    MOZ_ASSERT(mScreen);
+    // Early out for when we're rendering directly to the context's 'screen'.
+    if (!aNeedsReadBuffer && !aCF.samples)
+        return true;
+
+    MakeCurrent();
+    ContextFormat cf(aCF);
+    GLFormats formats = ChooseGLFormats(cf);
+
+    GLuint texture = 0;
+    if (aNeedsReadBuffer)
+        CreateTextureForOffscreen(formats, aSize, texture);
+
+    GLuint colorMSRB = 0;
+    GLuint depthRB = 0;
+    GLuint stencilRB = 0;
+    CreateRenderbuffersForOffscreen(formats, aSize, colorMSRB, depthRB, stencilRB);
+
+    GLuint drawFBO = 0;
+    GLuint readFBO = 0;
+    if (!AssembleOffscreenFBOs(colorMSRB, depthRB, stencilRB, texture,
+                               drawFBO, readFBO))
+    {
+        fDeleteFramebuffers(1, &drawFBO);
+        fDeleteFramebuffers(1, &readFBO);
+        fDeleteRenderbuffers(1, &colorMSRB);
+        fDeleteRenderbuffers(1, &depthRB);
+        fDeleteRenderbuffers(1, &stencilRB);
+        fDeleteTextures(1, &texture);
+
+        return false;
+    }
 
-    if (!mScreen->PublishFrame(OffscreenSize()))
-        return false;
+    // Success, so switch everything out.
+    // Store current user FBO bindings.
+    GLuint boundDrawFBO = GetUserBoundDrawFBO();
+    GLuint boundReadFBO = GetUserBoundReadFBO();
+
+    // Replace with the new hotness
+    std::swap(mOffscreenDrawFBO, drawFBO);
+    std::swap(mOffscreenReadFBO, readFBO);
+    std::swap(mOffscreenColorRB, colorMSRB);
+    std::swap(mOffscreenDepthRB, depthRB);
+    std::swap(mOffscreenStencilRB, stencilRB);
+    std::swap(mOffscreenTexture, texture);
+
+    // Delete the old and busted
+    fDeleteFramebuffers(1, &drawFBO);
+    fDeleteFramebuffers(1, &readFBO);
+    fDeleteRenderbuffers(1, &colorMSRB);
+    fDeleteRenderbuffers(1, &depthRB);
+    fDeleteRenderbuffers(1, &stencilRB);
+    fDeleteTextures(1, &texture);
+
+    // Rebind user FBOs, in case anything changed internally.
+    BindUserDrawFBO(boundDrawFBO);
+    BindUserReadFBO(boundReadFBO);
+
+    // Newly-created buffers are...unlikely to match.
+    ForceDirtyFBOs();
+
+    // Finish up.
+    mOffscreenSize = aSize;
+    mOffscreenActualSize = aSize;
+    mActualFormat = cf;
+
+    if (DebugMode()) {
+        printf_stderr("Resized %dx%d offscreen FBO: r: %d g: %d b: %d a: %d depth: %d stencil: %d samples: %d\n",
+                      mOffscreenActualSize.width, mOffscreenActualSize.height,
+                      mActualFormat.red, mActualFormat.green, mActualFormat.blue, mActualFormat.alpha,
+                      mActualFormat.depth, mActualFormat.stencil, mActualFormat.samples);
+    }
 
     return true;
 }
 
-SharedSurface*
-GLContext::RequestFrame()
+void
+GLContext::DeleteOffscreenFBOs()
 {
-    MOZ_ASSERT(mScreen);
+    fDeleteFramebuffers(1, &mOffscreenDrawFBO);
+    fDeleteFramebuffers(1, &mOffscreenReadFBO);
+    fDeleteTextures(1, &mOffscreenTexture);
+    fDeleteRenderbuffers(1, &mOffscreenColorRB);
+    fDeleteRenderbuffers(1, &mOffscreenDepthRB);
+    fDeleteRenderbuffers(1, &mOffscreenStencilRB);
 
-    return mScreen->Stream()->SwapConsumer();
+    mOffscreenDrawFBO = 0;
+    mOffscreenReadFBO = 0;
+    mOffscreenTexture = 0;
+    mOffscreenColorRB = 0;
+    mOffscreenDepthRB = 0;
+    mOffscreenStencilRB = 0;
 }
 
-
-
 void
 GLContext::ClearSafely()
 {
     // bug 659349 --- we must be very careful here: clearing a GL framebuffer is nontrivial, relies on a lot of state,
     // and in the case of the backbuffer of a WebGL context, state is exposed to scripts.
     //
     // The code here is taken from WebGLContext::ForceClearFramebufferWithDefaultValues, but I didn't find a good way of
     // sharing code with it. WebGL's code is somewhat performance-critical as it is typically called on every frame, so
@@ -1282,17 +1230,17 @@ GLContext::ClearSafely()
     fGetIntegerv(LOCAL_GL_STENCIL_BACK_WRITEMASK, &stencilWriteMaskBack);
     fGetFloatv(LOCAL_GL_COLOR_CLEAR_VALUE, colorClearValue);
     fGetFloatv(LOCAL_GL_DEPTH_CLEAR_VALUE, &depthClearValue);
     fGetIntegerv(LOCAL_GL_STENCIL_CLEAR_VALUE, &stencilClearValue);
 
     // prepare GL state for clearing
     fDisable(LOCAL_GL_SCISSOR_TEST);
     fDisable(LOCAL_GL_DITHER);
-    PushViewportRect(nsIntRect(0, 0, OffscreenSize().width, OffscreenSize().height));
+    PushViewportRect(nsIntRect(0, 0, mOffscreenSize.width, mOffscreenSize.height));
 
     fColorMask(1, 1, 1, 1);
     fClearColor(0.f, 0.f, 0.f, 0.f);
 
     fDepthMask(1);
     fClearDepth(1.0f);
 
     fStencilMask(0xffffffff);
@@ -1330,34 +1278,44 @@ GLContext::ClearSafely()
     if (scissorTestEnabled)
         fEnable(LOCAL_GL_SCISSOR_TEST);
     else
         fDisable(LOCAL_GL_SCISSOR_TEST);
 
 }
 
 void
+GLContext::UpdateActualFormat()
+{
+    ContextFormat nf;
+
+    fGetIntegerv(LOCAL_GL_RED_BITS, (GLint*) &nf.red);
+    fGetIntegerv(LOCAL_GL_GREEN_BITS, (GLint*) &nf.green);
+    fGetIntegerv(LOCAL_GL_BLUE_BITS, (GLint*) &nf.blue);
+    fGetIntegerv(LOCAL_GL_ALPHA_BITS, (GLint*) &nf.alpha);
+    fGetIntegerv(LOCAL_GL_DEPTH_BITS, (GLint*) &nf.depth);
+    fGetIntegerv(LOCAL_GL_STENCIL_BITS, (GLint*) &nf.stencil);
+
+    mActualFormat = nf;
+}
+
+void
 GLContext::MarkDestroyed()
 {
     if (IsDestroyed())
         return;
 
     if (MakeCurrent()) {
-        DestroyScreenBuffer();
-
-        // This is for Blit{Tex,FB}To{TexFB}.
+        DeleteOffscreenFBOs();
         DeleteTexBlitProgram();
 
-        // Likely used by OGL Layers.
         fDeleteProgram(mBlitProgram);
         mBlitProgram = 0;
         fDeleteFramebuffers(1, &mBlitFramebuffer);
         mBlitFramebuffer = 0;
-
-        mTexGarbageBin->GLContextTeardown();
     } else {
         NS_WARNING("MakeCurrent() failed during MarkDestroyed! Skipping GL object teardown.");
     }
 
     mSymbols.Zero();
 }
 
 static void SwapRAndBComponents(gfxImageSurface* surf)
@@ -1554,243 +1512,123 @@ GLContext::ReadTextureImage(GLuint aText
     fBindFramebuffer(LOCAL_GL_FRAMEBUFFER, oldfb);
     fUseProgram(oldprog);
 
     PopViewportRect();
 
     return isurf.forget();
 }
 
-static bool
-GetActualReadFormats(GLContext* gl, GLenum destFormat, GLenum destType,
-                     GLenum& readFormat, GLenum& readType)
-{
-    if (destFormat == LOCAL_GL_RGBA &&
-        destType == LOCAL_GL_UNSIGNED_BYTE)
-    {
-        readFormat = destFormat;
-        readType = destType;
-        return true;
-    }
-
-    bool fallback = true;
+static void
+GetOptimalReadFormats(GLContext* gl, GLenum& format, GLenum& type) {
     if (gl->IsGLES2()) {
-        GLenum auxFormat = 0;
-        GLenum auxType = 0;
-
-        gl->fGetIntegerv(LOCAL_GL_IMPLEMENTATION_COLOR_READ_FORMAT, (GLint*)&auxFormat);
-        gl->fGetIntegerv(LOCAL_GL_IMPLEMENTATION_COLOR_READ_TYPE, (GLint*)&auxType);
+        bool has_BGRA_UByte = false;
+        if (gl->IsExtensionSupported(gl::GLContext::EXT_bgra)) {
+          has_BGRA_UByte = true;
+        } else if (gl->IsExtensionSupported(gl::GLContext::EXT_read_format_bgra) ||
+                   gl->IsExtensionSupported(gl::GLContext::IMG_read_format)) {
+            // Note that these extensions are not required to query this value.
+            // However, we should never get back BGRA unless one of these is supported.
+            GLint auxFormat = 0;
+            GLint auxType = 0;
 
-        if (destFormat == auxFormat &&
-            destType == auxType)
-        {
-            fallback = false;
+            gl->fGetIntegerv(LOCAL_GL_IMPLEMENTATION_COLOR_READ_FORMAT, &auxFormat);
+            gl->fGetIntegerv(LOCAL_GL_IMPLEMENTATION_COLOR_READ_TYPE, &auxType);
+
+            if (auxFormat == LOCAL_GL_BGRA && auxType == LOCAL_GL_UNSIGNED_BYTE)
+              has_BGRA_UByte = true;
         }
+
+        format = has_BGRA_UByte ? LOCAL_GL_BGRA : LOCAL_GL_RGBA;
+        type = LOCAL_GL_UNSIGNED_BYTE;
     } else {
-        switch (destFormat) {
-            case LOCAL_GL_RGB: {
-                if (destType == LOCAL_GL_UNSIGNED_SHORT_5_6_5_REV)
-                    fallback = false;
-                break;
-            }
-            case LOCAL_GL_BGRA: {
-                if (destType == LOCAL_GL_UNSIGNED_INT_8_8_8_8_REV)
-                    fallback = false;
-                break;
-            }
-        }
-    }
-
-    if (fallback) {
-        readFormat = LOCAL_GL_RGBA;
-        readType = LOCAL_GL_UNSIGNED_BYTE;
-        return false;
-    } else {
-        readFormat = destFormat;
-        readType = destType;
-        return true;
+        // defaults for desktop
+        format = LOCAL_GL_BGRA;
+        type = LOCAL_GL_UNSIGNED_INT_8_8_8_8_REV;
     }
 }
 
 void
 GLContext::ReadScreenIntoImageSurface(gfxImageSurface* dest)
 {
-    ScopedBindFramebuffer autoFB(this, 0);
+    GLuint boundFB = 0;
+    fGetIntegerv(LOCAL_GL_FRAMEBUFFER_BINDING, (GLint*)&boundFB);
+    fBindFramebuffer(LOCAL_GL_FRAMEBUFFER, 0);
 
     ReadPixelsIntoImageSurface(dest);
+
+    fBindFramebuffer(LOCAL_GL_FRAMEBUFFER, boundFB);
 }
 
 void
 GLContext::ReadPixelsIntoImageSurface(gfxImageSurface* dest)
 {
-    MakeCurrent();
-    MOZ_ASSERT(dest->GetSize() != gfxIntSize(0, 0));
-
-    /* ImageFormatARGB32:
-     * RGBA+UByte: be[RGBA], le[ABGR]
-     * RGBA+UInt: le[RGBA]
-     * BGRA+UInt: le[BGRA]
-     * BGRA+UIntRev: le[ARGB]
-     *
-     * ImageFormatRGB16_565:
-     * RGB+UShort: le[rrrrrggg,gggbbbbb]
-     */
-    bool hasAlpha = dest->Format() == gfxASurface::ImageFormatARGB32;
-
-    int destPixelSize;
-    GLenum destFormat;
-    GLenum destType;
-
-    switch (dest->Format()) {
-        case gfxASurface::ImageFormatRGB24: // XRGB
-        case gfxASurface::ImageFormatARGB32:
-            destPixelSize = 4;
-            // Needs host (little) endian ARGB.
-            destFormat = LOCAL_GL_BGRA;
-            destType = LOCAL_GL_UNSIGNED_INT_8_8_8_8_REV;
-            break;
-
-        case gfxASurface::ImageFormatRGB16_565:
-            destPixelSize = 2;
-            destFormat = LOCAL_GL_RGB;
-            destType = LOCAL_GL_UNSIGNED_SHORT_5_6_5_REV;
-            break;
-
-        default:
-            MOZ_NOT_REACHED("Bad format.");
-            return;
-    }
-    MOZ_ASSERT(dest->Stride() == dest->Width() * destPixelSize);
-
-    GLenum readFormat = destFormat;
-    GLenum readType = destType;
-    bool needsTempSurf = !GetActualReadFormats(this,
-                                               destFormat, destType,
-                                               readFormat, readType);
+    MOZ_ASSERT(dest->Format() == gfxASurface::ImageFormatARGB32 ||
+               dest->Format() == gfxASurface::ImageFormatRGB24);
 
-    nsAutoPtr<gfxImageSurface> tempSurf;
-    gfxImageSurface* readSurf = nullptr;
-    int readPixelSize = 0;
-    if (needsTempSurf) {
-        if (DebugMode()) {
-            NS_WARNING("Needing intermediary surface for ReadPixels. This will be slow!");
-        }
-        gfxASurface::gfxImageFormat readFormatGFX;
-
-        switch (readFormat) {
-            case LOCAL_GL_RGBA:
-            case LOCAL_GL_BGRA: {
-                readFormatGFX = hasAlpha ? gfxASurface::ImageFormatARGB32
-                                         : gfxASurface::ImageFormatRGB24;
-                break;
-            }
-            case LOCAL_GL_RGB: {
-                MOZ_ASSERT(readPixelSize == 2);
-                MOZ_ASSERT(readType == LOCAL_GL_UNSIGNED_SHORT_5_6_5_REV);
-                readFormatGFX = gfxASurface::ImageFormatRGB16_565;
-                break;
-            }
-            default: {
-                MOZ_NOT_REACHED("Bad read format.");
-                return;
-            }
-        }
+    MOZ_ASSERT(dest->Stride() == dest->Width() * 4);
+    MOZ_ASSERT(dest->Format() == gfxASurface::ImageFormatARGB32 ||
+               dest->Format() == gfxASurface::ImageFormatRGB24);
 
-        switch (readType) {
-            case LOCAL_GL_UNSIGNED_BYTE: {
-                MOZ_ASSERT(readFormat == LOCAL_GL_RGBA);
-                readPixelSize = 4;
-                break;
-            }
-            case LOCAL_GL_UNSIGNED_INT_8_8_8_8_REV: {
-                MOZ_ASSERT(readFormat == LOCAL_GL_BGRA);
-                readPixelSize = 4;
-                break;
-            }
-            case LOCAL_GL_UNSIGNED_SHORT_5_6_5_REV: {
-                MOZ_ASSERT(readFormat == LOCAL_GL_RGB);
-                readPixelSize = 2;
-                break;
-            }
-            default: {
-                MOZ_NOT_REACHED("Bad read type.");
-                return;
-            }
-        }
+    MOZ_ASSERT(dest->Stride() == dest->Width() * 4);
 
-        tempSurf = new gfxImageSurface(dest->GetSize(), readFormatGFX, false);
-        readSurf = tempSurf;
-    } else {
-        readPixelSize = destPixelSize;
-        readSurf = dest;
-    }
-    MOZ_ASSERT(readPixelSize);
+    MakeCurrent();
 
     GLint currentPackAlignment = 0;
     fGetIntegerv(LOCAL_GL_PACK_ALIGNMENT, &currentPackAlignment);
 
-    if (currentPackAlignment != readPixelSize)
-        fPixelStorei(LOCAL_GL_PACK_ALIGNMENT, readPixelSize);
+    if (currentPackAlignment != 4)
+        fPixelStorei(LOCAL_GL_PACK_ALIGNMENT, 4);
+
+    GLenum format;
+    GLenum datatype;
+    GetOptimalReadFormats(this, format, datatype);
 
     GLsizei width = dest->Width();
     GLsizei height = dest->Height();
 
-    readSurf->Flush();
     fReadPixels(0, 0,
                 width, height,
-                readFormat, readType,
-                readSurf->Data());
-    readSurf->MarkDirty();
-
-    if (currentPackAlignment != readPixelSize)
-        fPixelStorei(LOCAL_GL_PACK_ALIGNMENT, currentPackAlignment);
-
-    if (readSurf != dest) {
-        MOZ_ASSERT(readFormat == LOCAL_GL_RGBA);
-        MOZ_ASSERT(readType == LOCAL_GL_UNSIGNED_BYTE);
-        // So we just copied in RGBA in big endian, or le: 0xAABBGGRR.
-        // We want 0xAARRGGBB, so swap R and B:
-        dest->Flush();
-        SwapRAndBComponents(readSurf);
-        dest->MarkDirty();
-
-        gfxContext ctx(dest);
-        ctx.SetOperator(gfxContext::OPERATOR_SOURCE);
-        ctx.SetSource(readSurf);
-        ctx.Paint();
-    }
+                format, datatype,
+                dest->Data());
 
     // Check if GL is giving back 1.0 alpha for
     // RGBA reads to RGBA images from no-alpha buffers.
 #ifdef XP_MACOSX
     if (WorkAroundDriverBugs() &&
         mVendor == VendorNVIDIA &&
         dest->Format() == gfxASurface::ImageFormatARGB32 &&
         width && height)
     {
         GLint alphaBits = 0;
         fGetIntegerv(LOCAL_GL_ALPHA_BITS, &alphaBits);
         if (!alphaBits) {
             const uint32_t alphaMask = gfxPackedPixelNoPreMultiply(0xff,0,0,0);
 
-            dest->Flush();
             uint32_t* itr = (uint32_t*)dest->Data();
             uint32_t testPixel = *itr;
             if ((testPixel & alphaMask) != alphaMask) {
                 // We need to set the alpha channel to 1.0 manually.
                 uint32_t* itrEnd = itr + width*height;  // Stride is guaranteed to be width*4.
 
                 for (; itr != itrEnd; itr++) {
                     *itr |= alphaMask;
                 }
             }
-            dest->MarkDirty();
         }
     }
 #endif
+
+    // Output should be in BGRA, so swap if RGBA.
+    if (format == LOCAL_GL_RGBA) {
+        SwapRAndBComponents(dest);
+    }
+
+    if (currentPackAlignment != 4)
+        fPixelStorei(LOCAL_GL_PACK_ALIGNMENT, currentPackAlignment);
 }
 
 void
 GLContext::BlitTextureImage(TextureImage *aSrc, const nsIntRect& aSrcRect,
                             TextureImage *aDst, const nsIntRect& aDstRect)
 {
     NS_ASSERTION(!aSrc->InUpdate(), "Source texture is in update!");
     NS_ASSERTION(!aDst->InUpdate(), "Destination texture is in update!");
@@ -2021,19 +1859,16 @@ GLContext::UploadSurfaceToTexture(gfxASu
         // If a pixel buffer is bound the data pointer parameter is relative
         // to the start of the data block.
         if (!aPixelBuffer) {
               data = imageSurface->Data();
         }
         data += DataOffset(imageSurface, aSrcPoint);
     }
 
-    MOZ_ASSERT(imageSurface);
-    imageSurface->Flush();
-
     GLenum format;
     GLenum type;
     int32_t pixelSize = gfxASurface::BytePerPixelFromFormat(imageSurface->Format());
     ShaderProgramType shader;
 
     switch (imageSurface->Format()) {
         case gfxASurface::ImageFormatARGB32:
             format = LOCAL_GL_RGBA;
@@ -2818,125 +2653,10 @@ GLContext::ReportOutstandingNames()
     ReportArrayContents("Outstanding Programs", mTrackedPrograms);
     ReportArrayContents("Outstanding Shaders", mTrackedShaders);
     ReportArrayContents("Outstanding Framebuffers", mTrackedFramebuffers);
     ReportArrayContents("Outstanding Renderbuffers", mTrackedRenderbuffers);
 }
 
 #endif /* DEBUG */
 
-
-void
-GLContext::GuaranteeResolve()
-{
-   mScreen->AssureBlitted();
-   fFinish();
-}
-
-const gfxIntSize&
-GLContext::OffscreenSize() const
-{
-    MOZ_ASSERT(IsOffscreen());
-    return mScreen->Size();
-}
-
-bool
-GLContext::CreateScreenBufferImpl(const gfxIntSize& size, const SurfaceCaps& caps)
-{
-    GLScreenBuffer* newScreen = GLScreenBuffer::Create(this, size, caps);
-    if (!newScreen)
-        return false;
-
-    if (!newScreen->PublishFrame(size)) {
-        delete newScreen;
-        return false;
-    }
-
-    DestroyScreenBuffer();
-
-    // This will rebind to 0 (Screen) if needed when
-    // it falls out of scope.
-    ScopedBindFramebuffer autoFB(this);
-
-    mScreen = newScreen;
-
-    return true;
-}
-
-bool
-GLContext::ResizeScreenBuffer(const gfxIntSize& size)
-{
-    if (!IsOffscreenSizeAllowed(size))
-        return false;
-
-    return mScreen->PublishFrame(size);
-}
-
-
-void
-GLContext::DestroyScreenBuffer()
-{
-    delete mScreen;
-    mScreen = nullptr;
-}
-
-void
-GLContext::ForceDirtyScreen()
-{
-    ScopedBindFramebuffer autoFB(0);
-
-    BeforeGLDrawCall();
-    // no-op; just pretend we did something
-    AfterGLDrawCall();
-}
-
-void
-GLContext::CleanDirtyScreen()
-{
-    ScopedBindFramebuffer autoFB(0);
-
-    BeforeGLReadCall();
-    // no-op; we just want to make sure the Read FBO is updated if it needs to be
-    AfterGLReadCall();
-}
-
-void
-GLContext::EmptyTexGarbageBin()
-{
-   TexGarbageBin()->EmptyGarbage();
-}
-
-
-void
-TextureGarbageBin::GLContextTeardown()
-{
-    EmptyGarbage();
-
-    MutexAutoLock lock(mMutex);
-    mGL = nullptr;
-}
-
-void
-TextureGarbageBin::Trash(GLuint tex)
-{
-    MutexAutoLock lock(mMutex);
-    if (!mGL)
-        return;
-
-    mGarbageTextures.push(tex);
-}
-
-void
-TextureGarbageBin::EmptyGarbage()
-{
-    MutexAutoLock lock(mMutex);
-    if (!mGL)
-        return;
-
-    while (!mGarbageTextures.empty()) {
-        GLuint tex = mGarbageTextures.top();
-        mGarbageTextures.pop();
-        mGL->fDeleteTextures(1, &tex);
-    }
-}
-
 } /* namespace gl */
 } /* namespace mozilla */
--- a/gfx/gl/GLContext.h
+++ b/gfx/gl/GLContext.h
@@ -8,18 +8,16 @@
 
 #include <stdio.h>
 #include <algorithm>
 #if defined(XP_UNIX)
 #include <stdint.h>
 #endif
 #include <string.h>
 #include <ctype.h>
-#include <set>
-#include <stack>
 
 #ifdef WIN32
 #include <windows.h>
 #endif
 
 #include "GLDefs.h"
 #include "GLLibraryLoader.h"
 #include "gfxASurface.h"
@@ -33,90 +31,143 @@
 
 #include "nsDataHashtable.h"
 #include "nsHashKeys.h"
 #include "nsRegion.h"
 #include "nsAutoPtr.h"
 #include "nsThreadUtils.h"
 #include "GLContextTypes.h"
 #include "GLTextureImage.h"
-#include "SurfaceTypes.h"
-#include "GLScreenBuffer.h"
 
 typedef char realGLboolean;
 
 #include "GLContextSymbols.h"
 
 #include "mozilla/mozalloc.h"
 #include "mozilla/Preferences.h"
-#include "mozilla/StandardInteger.h"
-#include "mozilla/Mutex.h"
 
 namespace android {
-    class GraphicBuffer;
+class GraphicBuffer;
 }
 
 namespace mozilla {
-    namespace gfx {
-        class SharedSurface;
-        struct SurfaceCaps;
-    }
-
-    namespace gl {
-        class GLContext;
-        class GLLibraryEGL;
-        class GLScreenBuffer;
-        class TextureGarbageBin;
+  namespace layers {
+    class LayerManagerOGL;
+    class ColorTextureLayerProgram;
+  }
+
+namespace gl {
+class GLContext;
+
+typedef uintptr_t SharedTextureHandle;
+
+struct THEBES_API ContextFormat
+{
+    static const ContextFormat BasicRGBA32Format;
+
+    enum StandardContextFormat {
+        Empty,
+        BasicRGBA32,
+        StrictBasicRGBA32,
+        BasicRGB24,
+        StrictBasicRGB24,
+        BasicRGB16_565,
+        StrictBasicRGB16_565
+    };
+
+    ContextFormat() {
+        memset(this, 0, sizeof(ContextFormat));
     }
 
-    namespace layers {
-        class ColorTextureLayerProgram;
-        class LayerManagerOGL;
+    ContextFormat(const StandardContextFormat cf) {
+        memset(this, 0, sizeof(ContextFormat));
+        switch (cf) {
+        case BasicRGBA32:
+            red = green = blue = alpha = 8;
+            minRed = minGreen = minBlue = minAlpha = 1;
+            break;
+
+        case StrictBasicRGBA32:
+            red = green = blue = alpha = 8;
+            minRed = minGreen = minBlue = minAlpha = 8;
+            break;
+
+        case BasicRGB24:
+            red = green = blue = 8;
+            minRed = minGreen = minBlue = 1;
+            break;
+
+        case StrictBasicRGB24:
+            red = green = blue = 8;
+            minRed = minGreen = minBlue = 8;
+            break;
+
+        case StrictBasicRGB16_565:
+            red = minRed = 5;
+            green = minGreen = 6;
+            blue = minBlue = 5;
+            break;
+
+        default:
+            break;
+        }
     }
-}
-
-namespace mozilla {
-namespace gl {
-typedef uintptr_t SharedTextureHandle;
+
+    int depth, minDepth;
+    int stencil, minStencil;
+    int red, minRed;
+    int green, minGreen;
+    int blue, minBlue;
+    int alpha, minAlpha;
+    int samples;
+
+    int colorBits() const { return red + green + blue; }
+};
 
 class GLContext
     : public GLLibraryLoader
 {
     NS_INLINE_DECL_THREADSAFE_REFCOUNTING(GLContext)
-
-protected:
-    typedef class gfx::SharedSurface SharedSurface;
-    typedef gfx::SharedSurfaceType SharedSurfaceType;
-
 public:
-    typedef struct gfx::SurfaceCaps SurfaceCaps;
-
-    GLContext(const SurfaceCaps& caps,
-              GLContext* sharedContext = nullptr,
-              bool isOffscreen = false)
+    GLContext(const ContextFormat& aFormat,
+              bool aIsOffscreen = false,
+              GLContext *aSharedContext = nullptr)
       : mTexBlit_Buffer(0),
         mTexBlit_VertShader(0),
         mTexBlit_FragShader(0),
         mTexBlit_Program(0),
         mTexBlit_UseDrawNotCopy(false),
+        mUserBoundDrawFBO(0),
+        mUserBoundReadFBO(0),
+        mInternalBoundDrawFBO(0),
+        mInternalBoundReadFBO(0),
+#ifdef DEBUG
+        mInInternalBindingMode_DrawFBO(true),
+        mInInternalBindingMode_ReadFBO(true),
+#endif
+        mOffscreenFBOsDirty(false),
         mInitialized(false),
-        mIsOffscreen(isOffscreen),
+        mIsOffscreen(aIsOffscreen),
         mIsGLES2(false),
         mIsGlobalSharedContext(false),
         mHasRobustness(false),
         mContextLost(false),
         mVendor(-1),
         mRenderer(-1),
-        mSharedContext(sharedContext),
+        mCreationFormat(aFormat),
+        mSharedContext(aSharedContext),
+        mOffscreenTexture(0),
         mFlipped(false),
         mBlitProgram(0),
         mBlitFramebuffer(0),
-        mCaps(caps),
-        mScreen(nullptr),
-        mLockedSurface(nullptr),
+        mOffscreenDrawFBO(0),
+        mOffscreenReadFBO(0),
+        mOffscreenColorRB(0),
+        mOffscreenDepthRB(0),
+        mOffscreenStencilRB(0),
         mMaxTextureSize(0),
         mMaxCubeMapTextureSize(0),
         mMaxTextureImageSize(0),
         mMaxRenderbufferSize(0),
         mNeedsTextureSizeChecks(false),
         mWorkAroundDriverBugs(true)
 #ifdef DEBUG
         , mGLError(LOCAL_GL_NO_ERROR)
@@ -237,22 +288,23 @@ public:
         // (that is, when the main thread is no longer get-able) can cause them
         // to leak. See Bug 741319, and Bug 744115.
         nsCOMPtr<nsIThread> mainThread;
         if (NS_SUCCEEDED(NS_GetMainThread(getter_AddRefs(mainThread)))) {
             mOwningThread->Dispatch(event, NS_DISPATCH_NORMAL);
         }
     }
 
-    virtual EGLContext GetEGLContext() { return nullptr; }
-    virtual GLLibraryEGL* GetLibraryEGL() { return nullptr; }
-
-    virtual void MakeCurrent_EGLSurface(void* surf) {
-        MOZ_NOT_REACHED("Must be called against a GLContextEGL.");
-    }
+    const ContextFormat& CreationFormat() { return mCreationFormat; }
+    const ContextFormat& ActualFormat() { return mActualFormat; }
+
+    /**
+     * If this GL context has a D3D texture share handle, returns non-null.
+     */
+    virtual void *GetD3DShareHandle() { return nullptr; }
 
     /**
      * If this context is double-buffered, returns TRUE.
      */
     virtual bool IsDoubleBuffered() { return false; }
 
     /**
      * If this context is the GLES2 API, returns TRUE.
@@ -354,41 +406,86 @@ public:
 
     virtual bool BindExternalBuffer(GLuint texture, void* buffer) { return false; }
     virtual bool UnbindExternalBuffer(GLuint texture) { return false; }
 
     virtual already_AddRefed<TextureImage>
     CreateDirectTextureImage(android::GraphicBuffer* aBuffer, GLenum aWrapMode)
     { return nullptr; }
 
+    /*
+     * Offscreen support API
+     */
+
+    /*
+     * Bind aOffscreen's color buffer as a texture to the TEXTURE_2D
+     * target.  Returns TRUE on success, otherwise FALSE.  If
+     * aOffscreen is not an offscreen context, returns FALSE.  If
+     * BindOffscreenNeedsTexture() returns TRUE, then you should have
+     * a 2D texture name bound whose image will be replaced by the
+     * contents of the offscreen context.  If it returns FALSE,
+     * the current 2D texture binding will be replaced.
+     *
+     * After a successul call to BindTex2DOffscreen, UnbindTex2DOffscreen
+     * *must* be called once rendering is complete.
+     *
+     * The same texture unit must be active for Bind/Unbind of a given
+     * context.
+     */
+    virtual bool BindOffscreenNeedsTexture(GLContext *aOffscreen) {
+        return aOffscreen->mOffscreenTexture == 0;
+    }
+
+    virtual bool BindTex2DOffscreen(GLContext *aOffscreen) {
+        if (aOffscreen->GetContextType() != GetContextType()) {
+          return false;
+        }
+
+        if (!aOffscreen->mSharedContext ||
+            aOffscreen->mSharedContext != mSharedContext)
+        {
+            return false;
+        }
+
+        if (!aOffscreen->mOffscreenTexture) {
+            return false;
+        }
+
+        fBindTexture(LOCAL_GL_TEXTURE_2D, aOffscreen->mOffscreenTexture);
+
+        return true;
+    }
+
+    virtual void UnbindTex2DOffscreen(GLContext *aOffscreen) { }
+
+    bool IsOffscreen() {
+        return mIsOffscreen;
+    }
+    
     // Before reads from offscreen texture
-    void GuaranteeResolve();
+    void GuaranteeResolve() {
+        BlitDirtyFBOs();
+        fFinish();
+    }
 
 protected:
     GLuint mTexBlit_Buffer;
     GLuint mTexBlit_VertShader;
     GLuint mTexBlit_FragShader;
     GLuint mTexBlit_Program;
 
     bool mTexBlit_UseDrawNotCopy;
 
     bool UseTexQuadProgram();
     void DeleteTexBlitProgram();
 
 public:
-    // If you don't have |srcFormats| for the 2nd definition,
-    // then you'll need the framebuffer_blit extensions to use
-    // the first BlitFramebufferToFramebuffer.
     void BlitFramebufferToFramebuffer(GLuint srcFB, GLuint destFB,
                                       const gfxIntSize& srcSize,
                                       const gfxIntSize& destSize);
-    void BlitFramebufferToFramebuffer(GLuint srcFB, GLuint destFB,
-                                      const gfxIntSize& srcSize,
-                                      const gfxIntSize& destSize,
-                                      const GLFormats& srcFormats);
     void BlitTextureToFramebuffer(GLuint srcTex, GLuint destFB,
                                   const gfxIntSize& srcSize,
                                   const gfxIntSize& destSize);
     void BlitFramebufferToTexture(GLuint srcFB, GLuint destTex,
                                   const gfxIntSize& srcSize,
                                   const gfxIntSize& destSize);
     void BlitTextureToTexture(GLuint srcTex, GLuint destTex,
                               const gfxIntSize& srcSize,
@@ -397,35 +494,63 @@ public:
     /*
      * Resize the current offscreen buffer.  Returns true on success.
      * If it returns false, the context should be treated as unusable
      * and should be recreated.  After the resize, the viewport is not
      * changed; glViewport should be called as appropriate.
      *
      * Only valid if IsOffscreen() returns true.
      */
-    virtual bool ResizeOffscreen(const gfxIntSize& size) {
-        return ResizeScreenBuffer(size);
+    virtual bool ResizeOffscreen(const gfxIntSize& aNewSize) {
+        if (mOffscreenDrawFBO || mOffscreenReadFBO)
+            return ResizeOffscreenFBOs(aNewSize, mOffscreenReadFBO != 0);
+        return false;
     }
 
     /*
      * Return size of this offscreen context.
      *
      * Only valid if IsOffscreen() returns true.
      */
-    const gfxIntSize& OffscreenSize() const;
-
-    virtual bool SupportsFramebufferMultisample() const {
-        return IsExtensionSupported(EXT_framebuffer_multisample) ||
-               IsExtensionSupported(ANGLE_framebuffer_multisample);
+    gfxIntSize OffscreenSize() {
+        return mOffscreenSize;
+    }
+
+    /*
+     * In some cases, we have to allocate a bigger offscreen buffer
+     * than what's requested.  This is the bigger size.
+     *
+     * Only valid if IsOffscreen() returns true.
+     */
+    gfxIntSize OffscreenActualSize() {
+        return mOffscreenActualSize;
     }
 
-    virtual bool SupportsSplitFramebuffer() {
-        return IsExtensionSupported(EXT_framebuffer_blit) ||
-               IsExtensionSupported(ANGLE_framebuffer_blit);
+    /*
+     * If this context is FBO-backed, return the FBO or the color
+     * buffer texture.  If the context is not FBO-backed, 0 is
+     * returned (which is also a valid FBO binding).
+     *
+     * Only valid if IsOffscreen() returns true.
+     */
+    GLuint GetOffscreenFBO() {
+        // 0 is interpreted as (off)screen, whether for read or draw operations
+        return 0;
+    }
+
+    GLuint GetOffscreenTexture() {
+        return mOffscreenTexture;
+    }
+
+    virtual bool SupportsFramebufferMultisample() {
+        return IsExtensionSupported(EXT_framebuffer_multisample) || IsExtensionSupported(ANGLE_framebuffer_multisample);
+    }
+
+    virtual bool SupportsOffscreenSplit() {
+        return IsExtensionSupported(EXT_framebuffer_blit) || IsExtensionSupported(ANGLE_framebuffer_blit);
     }
 
 
     enum SharedTextureShareType {
         SameProcess = 0,
         CrossProcess
     };
 
@@ -501,121 +626,269 @@ public:
 
     /**
      * Detach Shared GL Handle from GL_TEXTURE_2D target
      */
     virtual void DetachSharedHandle(SharedTextureShareType shareType,
                                     SharedTextureHandle sharedHandle)
     { }
 
+private:
+    GLuint mUserBoundDrawFBO;
+    GLuint mUserBoundReadFBO;
+    GLuint mInternalBoundDrawFBO;
+    GLuint mInternalBoundReadFBO;
+
+public:
     void fBindFramebuffer(GLenum target, GLuint framebuffer) {
-        if (!mScreen) {
-            raw_fBindFramebuffer(target, framebuffer);
-            return;
-        }
-
         switch (target) {
-            case LOCAL_GL_DRAW_FRAMEBUFFER_EXT:
-                mScreen->BindDrawFB(framebuffer);
-                return;
-
-            case LOCAL_GL_READ_FRAMEBUFFER_EXT:
-                mScreen->BindReadFB(framebuffer);
-                return;
-
-            case LOCAL_GL_FRAMEBUFFER:
-                 mScreen->BindFB(framebuffer);
-                 return;
-
-            default:
-                // Nothing we care about, likely an error.
-                break;
-       }
-
-        raw_fBindFramebuffer(target, framebuffer);
-    }
-
-    void BindFB(GLuint fb) {
-        fBindFramebuffer(LOCAL_GL_FRAMEBUFFER, fb);
-        MOZ_ASSERT(!fb || fIsFramebuffer(fb));
-    }
-
-    void BindDrawFB(GLuint fb) {
-        fBindFramebuffer(LOCAL_GL_DRAW_FRAMEBUFFER_EXT, fb);
-    }
-
-    void BindReadFB(GLuint fb) {
-        fBindFramebuffer(LOCAL_GL_READ_FRAMEBUFFER_EXT, fb);
+          case LOCAL_GL_DRAW_FRAMEBUFFER_EXT:
+            mUserBoundDrawFBO = framebuffer;
+
+            if (framebuffer == 0) {
+                mInternalBoundDrawFBO = mOffscreenDrawFBO;
+            } else {
+                mInternalBoundDrawFBO = mUserBoundDrawFBO;
+            }
+
+            raw_fBindFramebuffer(LOCAL_GL_DRAW_FRAMEBUFFER_EXT,
+                                 mInternalBoundDrawFBO);
+            break;
+
+          case LOCAL_GL_READ_FRAMEBUFFER_EXT:
+            mUserBoundReadFBO = framebuffer;
+
+            if (framebuffer == 0) {
+                mInternalBoundReadFBO = mOffscreenReadFBO;
+            } else {
+                mInternalBoundReadFBO = mUserBoundReadFBO;
+            }
+
+            raw_fBindFramebuffer(LOCAL_GL_READ_FRAMEBUFFER_EXT,
+                                 mInternalBoundReadFBO);
+            break;
+
+          case LOCAL_GL_FRAMEBUFFER:
+            mUserBoundDrawFBO = mUserBoundReadFBO = framebuffer;
+
+            if (framebuffer == 0) {
+                mInternalBoundDrawFBO = mOffscreenDrawFBO;
+                mInternalBoundReadFBO = mOffscreenReadFBO;
+            } else {
+                mInternalBoundDrawFBO = mUserBoundDrawFBO;
+                mInternalBoundReadFBO = mUserBoundReadFBO;
+            }
+
+            if (SupportsOffscreenSplit()) {
+                raw_fBindFramebuffer(LOCAL_GL_DRAW_FRAMEBUFFER_EXT,
+                                     mInternalBoundDrawFBO);
+                raw_fBindFramebuffer(LOCAL_GL_READ_FRAMEBUFFER_EXT,
+                                     mInternalBoundReadFBO);
+            } else {
+                raw_fBindFramebuffer(LOCAL_GL_FRAMEBUFFER,
+                                     mInternalBoundDrawFBO);
+            }
+
+            break;
+
+          default:
+            raw_fBindFramebuffer(target, framebuffer);
+            break;
+        }
     }
 
     void fGetIntegerv(GLenum pname, GLint *params) {
-        if (!mScreen) {
-            raw_fGetIntegerv(pname, params);
-            return;
-        }
-
         switch (pname)
         {
             // LOCAL_GL_FRAMEBUFFER_BINDING is equal to
-            // LOCAL_GL_DRAW_FRAMEBUFFER_BINDING_EXT,
-            // so we don't need two cases.
-            case LOCAL_GL_DRAW_FRAMEBUFFER_BINDING_EXT:
-                *params = mScreen->GetDrawFB();
+            // LOCAL_GL_DRAW_FRAMEBUFFER_BINDING_EXT, so we don't need two
+            // cases.
+            case LOCAL_GL_FRAMEBUFFER_BINDING:
+                *params = GetUserBoundDrawFBO();
                 break;
 
             case LOCAL_GL_READ_FRAMEBUFFER_BINDING_EXT:
-                *params = mScreen->GetReadFB();
+                *params = GetUserBoundReadFBO();
+                break;
+
+            case LOCAL_GL_MAX_TEXTURE_SIZE:
+                *params = mMaxTextureSize;
+                break;
+
+            case LOCAL_GL_MAX_CUBE_MAP_TEXTURE_SIZE:
+                *params = mMaxCubeMapTextureSize;
+                break;
+
+            case LOCAL_GL_MAX_RENDERBUFFER_SIZE:
+                *params = mMaxRenderbufferSize;
                 break;
 
             default:
                 raw_fGetIntegerv(pname, params);
                 break;
         }
     }
 
-    GLuint GetDrawFB() {
-        if (mScreen)
-            return mScreen->GetDrawFB();
-
-        GLuint ret = 0;
-        GetUIntegerv(LOCAL_GL_DRAW_FRAMEBUFFER_BINDING_EXT, &ret);
-        return ret;
+#ifdef DEBUG
+    // See comment near BindInternalDrawFBO()
+    bool mInInternalBindingMode_DrawFBO;
+    bool mInInternalBindingMode_ReadFBO;
+#endif
+
+    GLuint GetUserBoundDrawFBO() {
+#ifdef DEBUG
+        MOZ_ASSERT(IsCurrent());
+
+        GLint ret = 0;
+        // Don't need a branch here, because:
+        // LOCAL_GL_DRAW_FRAMEBUFFER_BINDING_EXT == LOCAL_GL_FRAMEBUFFER_BINDING == 0x8CA6
+        // We use raw_ here because this is debug code and we need to see what
+        // the driver thinks.
+        raw_fGetIntegerv(LOCAL_GL_DRAW_FRAMEBUFFER_BINDING_EXT, &ret);
+
+        bool abort = false;
+
+        if (mInInternalBindingMode_DrawFBO) {
+            NS_ERROR("Draw FBO still bound internally!");
+            printf_stderr("Current internal draw FBO: %d, user: %d)\n", ret, mUserBoundDrawFBO);
+            abort = true;
+        }
+
+        if (mInternalBoundDrawFBO != (GLuint)ret) {
+            NS_ERROR("Draw FBO binding misprediction!");
+            printf_stderr("Bound draw FBO was: %d, Expected: %d\n", ret, mInternalBoundDrawFBO);
+            abort = true;
+        }
+
+        if (abort)
+            NS_ABORT();
+#endif
+
+        // We only ever expose the user's bound FBOs
+        return mUserBoundDrawFBO;
     }
 
-    GLuint GetReadFB() {
-        if (mScreen)
-            return mScreen->GetReadFB();
-
-        GLenum bindEnum = SupportsSplitFramebuffer() ? LOCAL_GL_READ_FRAMEBUFFER_BINDING_EXT
-                                                     : LOCAL_GL_FRAMEBUFFER_BINDING;
-
-        GLuint ret = 0;
-        GetUIntegerv(bindEnum, &ret);
-        return ret;
+    GLuint GetUserBoundReadFBO() {
+#ifdef DEBUG
+        MOZ_ASSERT(IsCurrent());
+
+        GLint ret = 0;
+        // We use raw_ here because this is debug code and we need to see what
+        // the driver thinks.
+        if (SupportsOffscreenSplit())
+            raw_fGetIntegerv(LOCAL_GL_READ_FRAMEBUFFER_BINDING_EXT, &ret);
+        else
+            raw_fGetIntegerv(LOCAL_GL_FRAMEBUFFER_BINDING, &ret);
+
+        bool abort = false;
+
+        if (mInInternalBindingMode_ReadFBO) {
+            NS_ERROR("Read FBO still bound internally!");
+            printf_stderr("Current internal read FBO: %d, user: %d)\n", ret, mUserBoundReadFBO);
+            abort = true;
+        }
+
+        if (mInternalBoundReadFBO != (GLuint)ret) {
+            NS_ERROR("Read FBO binding misprediction!");
+            printf_stderr("Bound read FBO was: %d, Expected: %d\n", ret, mInternalBoundReadFBO);
+            abort = true;
+        }
+
+        if (abort)
+            NS_ABORT();
+#endif
+
+        // We only ever expose the user's bound FBOs
+        return mUserBoundReadFBO;
+    }
+
+    void BindUserDrawFBO(GLuint name) {
+        if (SupportsOffscreenSplit())
+            fBindFramebuffer(LOCAL_GL_DRAW_FRAMEBUFFER_EXT, name);
+        else
+            fBindFramebuffer(LOCAL_GL_FRAMEBUFFER, name);
+#ifdef DEBUG
+        mInInternalBindingMode_DrawFBO = false;
+#endif
     }
 
-    GLuint GetFB() {
-        if (mScreen) {
-            // This has a very important extra assert that checks that we're
-            // not accidentally ignoring a situation where the draw and read
-            // FBs differ.
-            return mScreen->GetFB();
-        }
-
-        GLuint ret = 0;
-        GetUIntegerv(LOCAL_GL_FRAMEBUFFER_BINDING, &ret);
-        return ret;
+    void BindUserReadFBO(GLuint name) {
+        if (SupportsOffscreenSplit())
+            fBindFramebuffer(LOCAL_GL_READ_FRAMEBUFFER_EXT, name);
+        else
+            fBindFramebuffer(LOCAL_GL_FRAMEBUFFER, name);
+#ifdef DEBUG
+        mInInternalBindingMode_ReadFBO = false;
+#endif
+    }
+
+    GLuint GetUserBoundFBO() {
+        MOZ_ASSERT(GetUserBoundDrawFBO() == GetUserBoundReadFBO());
+        return GetUserBoundReadFBO();
+    }
+
+    void BindUserFBO(GLuint name) {
+        fBindFramebuffer(LOCAL_GL_FRAMEBUFFER, name);
+    }
+
+    // BindInternalDraw/ReadFBO() switch us over into 'internal binding mode'
+    //   for the corresponding Draw or Read binding.
+    // To exit internal binding mode, use BindUserDraw/ReadFBO().
+    // While in internal binding mode for Draw/Read, the corresponding
+    //   GetBoundUserDraw/ReadFBO() is undefined, and will trigger ABORT in DEBUG builds.
+    void BindInternalDrawFBO(GLuint name) {
+#ifdef DEBUG
+        mInInternalBindingMode_DrawFBO = true;
+#endif
+        if (SupportsOffscreenSplit())
+            raw_fBindFramebuffer(LOCAL_GL_DRAW_FRAMEBUFFER_EXT, name);
+        else
+            raw_fBindFramebuffer(LOCAL_GL_FRAMEBUFFER, name);
+
+        mInternalBoundDrawFBO = name;
+    }
+
+    void BindInternalReadFBO(GLuint name) {
+#ifdef DEBUG
+        mInInternalBindingMode_ReadFBO = true;
+#endif
+        if (SupportsOffscreenSplit())
+            raw_fBindFramebuffer(LOCAL_GL_READ_FRAMEBUFFER_EXT, name);
+        else
+            raw_fBindFramebuffer(LOCAL_GL_FRAMEBUFFER, name);
+
+        mInternalBoundReadFBO = name;
+    }
+
+    void BindInternalFBO(GLuint name) {
+        BindInternalDrawFBO(name);
+        BindInternalReadFBO(name);
     }
 
     void InitFramebuffers() {
         MakeCurrent();
-        BindFB(0);
+        BindUserDrawFBO(0);
+        BindUserReadFBO(0);
+    }
+
+    GLuint SwapUserDrawFBO(GLuint name) {
+        GLuint prev = GetUserBoundDrawFBO();
+        BindUserDrawFBO(name);
+        return prev;
+    }
+
+    GLuint SwapUserReadFBO(GLuint name) {
+        GLuint prev = GetUserBoundReadFBO();
+        BindUserReadFBO(name);
+        return prev;
     }
 
 private:
+    bool mOffscreenFBOsDirty;
+
     void GetShaderPrecisionFormatNonES2(GLenum shadertype, GLenum precisiontype, GLint* range, GLint* precision) {
         switch (precisiontype) {
             case LOCAL_GL_LOW_FLOAT:
             case LOCAL_GL_MEDIUM_FLOAT:
             case LOCAL_GL_HIGH_FLOAT:
                 // Assume IEEE 754 precision
                 range[0] = 127;
                 range[1] = 127;
@@ -631,30 +904,73 @@ private:
                 *precision = 0;
                 break;
         }
     }
 
     // Do whatever setup is necessary to draw to our offscreen FBO, if it's
     // bound.
     void BeforeGLDrawCall() {
+        if (mInternalBoundDrawFBO != mOffscreenDrawFBO)
+            return;
+
+        if (mOffscreenDrawFBO == mOffscreenReadFBO)
+            return;
+
+        mOffscreenFBOsDirty = true;
     }
 
     // Do whatever tear-down is necessary after drawing to our offscreen FBO,
     // if it's bound.
     void AfterGLDrawCall() {
-        if (mScreen)
-            mScreen->AfterDrawCall();
     }
 
     // Do whatever setup is necessary to read from our offscreen FBO, if it's
     // bound.
     void BeforeGLReadCall() {
-        if (mScreen)
-            mScreen->BeforeReadCall();
+        if (mInternalBoundReadFBO != mOffscreenReadFBO)
+            return;
+
+        if (mOffscreenDrawFBO == mOffscreenReadFBO)
+            return;
+
+        // If we're not dirty, there's no need to blit
+        if (!mOffscreenFBOsDirty)
+            return;
+
+        const bool scissor = fIsEnabled(LOCAL_GL_SCISSOR_TEST);
+        if (scissor)
+            fDisable(LOCAL_GL_SCISSOR_TEST);
+
+        // Store current bindings for restoring later
+        GLuint prevDraw = GetUserBoundDrawFBO();
+        GLuint prevRead = GetUserBoundReadFBO();
+
+        NS_ABORT_IF_FALSE(SupportsOffscreenSplit(), "Doesn't support offscreen split?");
+
+        // Manually setting internal bindings, entering internal mode
+        // Flip read/draw for blitting
+        BindInternalDrawFBO(mOffscreenReadFBO);
+        BindInternalReadFBO(mOffscreenDrawFBO);
+
+        GLint width = mOffscreenActualSize.width;
+        GLint height = mOffscreenActualSize.height;
+        raw_fBlitFramebuffer(0, 0, width, height,
+                             0, 0, width, height,
+                             LOCAL_GL_COLOR_BUFFER_BIT,
+                             LOCAL_GL_NEAREST);
+
+        // Reset to emulated user binding, exiting internal mode
+        BindUserDrawFBO(prevDraw);
+        BindUserReadFBO(prevRead);
+
+        if (scissor)
+            fEnable(LOCAL_GL_SCISSOR_TEST);
+
+        mOffscreenFBOsDirty = false;
     }
 
     // Do whatever tear-down is necessary after reading from our offscreen FBO,
     // if it's bound.
     void AfterGLReadCall() {
     }
 
 public:
@@ -708,18 +1024,35 @@ public:
         y = FixYValue(y, height);
 
         BeforeGLReadCall();
         raw_fCopyTexSubImage2D(target, level, xoffset, yoffset,
                                x, y, width, height);
         AfterGLReadCall();
     }
 
-    void ForceDirtyScreen();
-    void CleanDirtyScreen();
+    void ForceDirtyFBOs() {
+        GLuint draw = SwapUserDrawFBO(0);
+
+        BeforeGLDrawCall();
+        // no-op; just pretend we did something
+        AfterGLDrawCall();
+
+        BindUserDrawFBO(draw);
+    }
+
+    void BlitDirtyFBOs() {
+        GLuint read = SwapUserReadFBO(0);
+
+        BeforeGLReadCall();
+        // no-op; we just want to make sure the Read FBO is updated if it needs to be
+        AfterGLReadCall();
+
+        BindUserReadFBO(read);
+    }
 
     // Draw/Read
     void fBlitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter) {
         BeforeGLDrawCall();
         BeforeGLReadCall();
         raw_fBlitFramebuffer(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter);
         AfterGLReadCall();
         AfterGLDrawCall();
@@ -1086,21 +1419,16 @@ public:
         CONTEXT_INNOCENT_CONTEXT_RESET_ARB = 0x8254,
         CONTEXT_UNKNOWN_CONTEXT_RESET_ARB = 0x8255
     };
 
     bool HasRobustness() {
         return mHasRobustness;
     }
 
-    bool HasExt_FramebufferBlit() {
-        return IsExtensionSupported(EXT_framebuffer_blit) ||
-               IsExtensionSupported(ANGLE_framebuffer_blit);
-    }
-
 protected:
     bool mInitialized;
     bool mIsOffscreen;
     bool mIsGLES2;
     bool mIsGlobalSharedContext;
     bool mHasRobustness;
     bool mContextLost;
 
@@ -1120,214 +1448,128 @@ public:
 #ifdef DEBUG
         return sDebugMode;
 #else
         return 0;
 #endif
     }
 
 protected:
+
+    ContextFormat mCreationFormat;
     nsRefPtr<GLContext> mSharedContext;
 
     // The thread on which this context was created.
     nsCOMPtr<nsIThread> mOwningThread;
 
     GLContextSymbols mSymbols;
 
 #ifdef DEBUG
     // GLDebugMode will check that we don't send call
     // to a GLContext that isn't current on the current
     // thread.
     // Store the current context when binding to thread local
     // storage to support DebugMode on an arbitrary thread.
     static unsigned sCurrentGLContextTLS;
 #endif
+
+    void UpdateActualFormat();
+    ContextFormat mActualFormat;
+
+    gfxIntSize mOffscreenSize;
+    gfxIntSize mOffscreenActualSize;
+    GLuint mOffscreenTexture;
     bool mFlipped;
 
     // lazy-initialized things
     GLuint mBlitProgram, mBlitFramebuffer;
     void UseBlitProgram();
     void SetBlitFramebufferForDestTexture(GLuint aTexture);
 
-public:
-    // Assumes shares are created by all sharing with the same global context.
-    bool SharesWith(const GLContext* other) const {
-        MOZ_ASSERT(!this->mSharedContext || !this->mSharedContext->mSharedContext);
-        MOZ_ASSERT(!other->mSharedContext || !other->mSharedContext->mSharedContext);
-        MOZ_ASSERT(!this->mSharedContext ||
-                   !other->mSharedContext ||
-                   this->mSharedContext == other->mSharedContext);
-
-        const GLContext* thisShared = this->mSharedContext ? this->mSharedContext
-                                                           : this;
-        const GLContext* otherShared = other->mSharedContext ? other->mSharedContext
-                                                             : other;
-
-        return thisShared == otherShared;
-    }
-
-    bool InitOffscreen(const gfxIntSize& size, const SurfaceCaps& caps) {
-        if (!CreateScreenBuffer(size, caps))
+    // Helper to create/resize an offscreen FBO,
+    // for offscreen implementations that use FBOs.
+    // Note that it does -not- clear the resized buffers.
+    bool ResizeOffscreenFBOs(const ContextFormat& aCF, const gfxIntSize& aSize, const bool aNeedsReadBuffer);
+    bool ResizeOffscreenFBOs(const gfxIntSize& aSize, const bool aNeedsReadBuffer) {
+        if (!IsOffscreenSizeAllowed(aSize))
             return false;
 
-        InitFramebuffers();
-
-        mCaps = mScreen->Caps();
-        UpdateGLFormats(caps);
-        UpdatePixelFormat();
-
-        return true;
-    }
-
-protected:
-    // Note that it does -not- clear the resized buffers.
-    bool CreateScreenBuffer(const gfxIntSize& size, const SurfaceCaps& caps) {
-        if (!IsOffscreenSizeAllowed(size))
-            return false;
-
-        SurfaceCaps tryCaps = caps;
-        if (tryCaps.antialias) {
+        ContextFormat format(mCreationFormat);
+
+        if (format.samples) {
             // AA path
-            if (CreateScreenBufferImpl(size, tryCaps))
+            if (ResizeOffscreenFBOs(format, aSize, aNeedsReadBuffer))
                 return true;
 
-            NS_WARNING("CreateScreenBuffer failed to initialize an AA context! Falling back to no AA...");
-            tryCaps.antialias = false;
+            NS_WARNING("ResizeOffscreenFBOs failed to resize an AA context! Falling back to no AA...");
+            format.samples = 0;
         }
-        MOZ_ASSERT(!tryCaps.antialias);
-
-        if (CreateScreenBufferImpl(size, tryCaps))
+
+        if (ResizeOffscreenFBOs(format, aSize, aNeedsReadBuffer))
             return true;
 
-        NS_WARNING("CreateScreenBuffer failed to initialize non-AA context!");
+        NS_WARNING("ResizeOffscreenFBOs failed to resize non-AA context!");
         return false;
     }
 
-    bool CreateScreenBufferImpl(const gfxIntSize& size,
-                                const SurfaceCaps& caps);
-
-public:
-    bool ResizeScreenBuffer(const gfxIntSize& size);
-
-protected:
-    SurfaceCaps mCaps;
-    nsAutoPtr<GLFormats> mGLFormats;
-    nsAutoPtr<PixelBufferFormat> mPixelFormat;
-
+    struct GLFormats {
+        GLFormats()
+            : texColor(0)
+            , texColorType(0)
+            , rbColor(0)
+            , depthStencil(0)
+            , depth(0)
+            , stencil(0)
+            , samples(0)
+        {}
+
+        GLenum texColor;
+        GLenum texColorType;
+        GLenum rbColor;
+        GLenum depthStencil;
+        GLenum depth;
+        GLenum stencil;
+        GLsizei samples;
+    };
+
+    enum ColorByteOrder {
+      ForceRGBA,
+      DefaultByteOrder
+    };
+
+    GLFormats ChooseGLFormats(ContextFormat& aCF, GLContext::ColorByteOrder aByteOrder = GLContext::DefaultByteOrder);
+    void CreateTextureForOffscreen(const GLFormats& aFormats, const gfxIntSize& aSize,
+                                   GLuint& texture);
+    void CreateRenderbuffersForOffscreen(const GLContext::GLFormats& aFormats, const gfxIntSize& aSize,
+                                         GLuint& colorMSRB, GLuint& depthRB, GLuint& stencilRB);
+    bool AssembleOffscreenFBOs(const GLuint colorMSRB,
+                               const GLuint depthRB,
+                               const GLuint stencilRB,
+                               const GLuint texture,
+                               GLuint& drawFBO,
+                               GLuint& readFBO);
+
+    void DeleteOffscreenFBOs();
+
+    GLuint mOffscreenDrawFBO;
+    GLuint mOffscreenReadFBO;
+    GLuint mOffscreenColorRB;
+    GLuint mOffscreenDepthRB;
+    GLuint mOffscreenStencilRB;
+
+    // Clear to transparent black, with 0 depth and stencil,
+    // while preserving current ClearColor etc. values.
+    // Useful for resizing offscreen buffers.
 public:
-    void DetermineCaps();
-    const SurfaceCaps& Caps() const {
-        return mCaps;
-    }
-
-    // Only varies based on bpp16 and alpha.
-    GLFormats ChooseGLFormats(const SurfaceCaps& caps) const;
-    void UpdateGLFormats(const SurfaceCaps& caps) {
-        mGLFormats = new GLFormats(ChooseGLFormats(caps));
-    }
-
-    const GLFormats& GetGLFormats() const {
-        MOZ_ASSERT(mGLFormats);
-        return *mGLFormats;
-    }
-
-    PixelBufferFormat QueryPixelFormat();
-    void UpdatePixelFormat();
-
-    const PixelBufferFormat& GetPixelFormat() const {
-        MOZ_ASSERT(mPixelFormat);
-        return *mPixelFormat;
-    }
-
-
-    GLuint CreateTextureForOffscreen(const GLFormats& formats,
-                                     const gfxIntSize& size);
-    GLuint CreateTexture(GLenum internalFormat,
-                         GLenum format, GLenum type,
-                         const gfxIntSize& size);
-    GLuint CreateRenderbuffer(GLenum format,
-                              GLsizei samples,
-                              const gfxIntSize& size);
-    bool IsFramebufferComplete(GLuint fb, GLenum* status = nullptr);
-
-    // Pass null to an RB arg to disable its creation.
-    void CreateRenderbuffersForOffscreen(const GLFormats& formats,
-                                         const gfxIntSize& size,
-                                         bool multisample,
-                                         GLuint* colorMSRB,
-                                         GLuint* depthRB,
-                                         GLuint* stencilRB);
-
-    // Does not check completeness.
-    void AttachBuffersToFB(GLuint colorTex, GLuint colorRB,
-                           GLuint depthRB, GLuint stencilRB,
-                           GLuint fb);
-
-    // Passing null is fine if the value you'd get is 0.
-    bool AssembleOffscreenFBs(const GLuint colorMSRB,
-                              const GLuint depthRB,
-                              const GLuint stencilRB,
-                              const GLuint texture,
-                              GLuint* drawFB,
-                              GLuint* readFB);
-
-protected:
-    friend class GLScreenBuffer;
-    GLScreenBuffer* mScreen;
-
-    void DestroyScreenBuffer();
-
-    SharedSurface* mLockedSurface;
-
-public:
-    void LockSurface(SharedSurface* surf) {
-        MOZ_ASSERT(!mLockedSurface);
-        mLockedSurface = surf;
-    }
-
-    void UnlockSurface(SharedSurface* surf) {
-        MOZ_ASSERT(mLockedSurface == surf);
-        mLockedSurface = nullptr;
-    }
-
-    SharedSurface* GetLockedSurface() const {
-        return mLockedSurface;
-    }
-
-    bool IsOffscreen() const {
-        return mScreen;
-    }
-
-    GLScreenBuffer* Screen() const {
-        return mScreen;
-    }
-
-    bool PublishFrame();
-    SharedSurface* RequestFrame();
-
-    /* Clear to transparent black, with 0 depth and stencil,
-     * while preserving current ClearColor etc. values.
-     * Useful for resizing offscreen buffers.
-     */
     void ClearSafely();
 
     bool WorkAroundDriverBugs() const { return mWorkAroundDriverBugs; }
 
 protected:
-    nsRefPtr<TextureGarbageBin> mTexGarbageBin;
-
-public:
-    TextureGarbageBin* TexGarbageBin() {
-        MOZ_ASSERT(mTexGarbageBin);
-        return mTexGarbageBin;
-    }
-
-    void EmptyTexGarbageBin();
-
-protected:
+
     nsDataHashtable<nsPtrHashKey<void>, void*> mUserData;
 
     void SetIsGLES2(bool aIsGLES2) {
         NS_ASSERTION(!mInitialized, "SetIsGLES2 can only be called before initialization!");
         mIsGLES2 = aIsGLES2;
     }
 
     bool InitWithPrefix(const char *prefix, bool trygl);
@@ -1350,17 +1592,16 @@ protected:
 
     nsTArray<nsIntRect> mViewportStack;
     nsTArray<nsIntRect> mScissorStack;
 
     GLint mMaxTextureSize;
     GLint mMaxCubeMapTextureSize;
     GLint mMaxTextureImageSize;
     GLint mMaxRenderbufferSize;
-    GLsizei mMaxSamples;
     bool mNeedsTextureSizeChecks;
     bool mWorkAroundDriverBugs;
 
     bool IsTextureSizeSafeToPassToDriver(GLenum target, GLsizei width, GLsizei height) const {
         if (mNeedsTextureSizeChecks) {
             // some drivers incorrectly handle some large texture sizes that are below the
             // max texture size that they report. So we check ourselves against our own values
             // (mMax[CubeMap]TextureSize).
@@ -1407,17 +1648,16 @@ public:
 #endif
 
 protected:
     GLenum mGLError;
 
 public:
 
     void BeforeGLCall(const char* glFunction) {
-        MOZ_ASSERT(IsCurrent());
         if (DebugMode()) {
             GLContext *currentGLContext = NULL;
 
             currentGLContext = (GLContext*)PR_GetThreadPrivate(sCurrentGLContextTLS);
 
             if (DebugMode() & DebugTrace)
                 printf_stderr("[gl:%p] > %s\n", this, glFunction);
             if (this != currentGLContext) {
@@ -2387,17 +2627,17 @@ private:
 
 public:
     void fBindRenderbuffer(GLenum target, GLuint renderbuffer) {
         BEFORE_GL_CALL;
         mSymbols.fBindRenderbuffer(target, renderbuffer);
         AFTER_GL_CALL;
     }
 
-    GLenum fCheckFramebufferStatus(GLenum target) {
+    GLenum fCheckFramebufferStatus (GLenum target) {
         BEFORE_GL_CALL;
         GLenum retval = mSymbols.fCheckFramebufferStatus(target);
         AFTER_GL_CALL;
         return retval;
     }
 
     void fFramebufferRenderbuffer(GLenum target, GLenum attachmentPoint, GLenum renderbufferTarget, GLuint renderbuffer) {
         BEFORE_GL_CALL;
@@ -2664,24 +2904,16 @@ public:
     }
 
     void fDeleteBuffers(GLsizei n, GLuint *names) {
         raw_fDeleteBuffers(n, names);
         TRACKING_CONTEXT(DeletedBuffers(this, n, names));
     }
 
     void fDeleteFramebuffers(GLsizei n, GLuint *names) {
-        if (mScreen) {
-            // Notify mScreen which framebuffers we're deleting.
-            // Otherwise, we will get framebuffer binding mispredictions.
-            for (int i = 0; i < n; i++) {
-                mScreen->DeletingFB(names[i]);
-            }
-        }
-
         if (n == 1 && *names == 0) {
             // Deleting framebuffer 0 causes hangs on the DROID. See bug 623228.
         } else {
             raw_fDeleteFramebuffers(n, names);
         }
         TRACKING_CONTEXT(DeletedFramebuffers(this, n, names));
     }
 
@@ -2761,24 +2993,16 @@ public:
     // OES_EGL_image (GLES)
     void fEGLImageTargetTexture2D(GLenum target, GLeglImage image) {
         BEFORE_GL_CALL;
         ASSERT_SYMBOL_PRESENT(fEGLImageTargetTexture2D);
         mSymbols.fEGLImageTargetTexture2D(target, image);
         AFTER_GL_CALL;
     }
 
-    void fEGLImageTargetRenderbufferStorage(GLenum target, GLeglImage image)
-    {
-        BEFORE_GL_CALL;
-        ASSERT_SYMBOL_PRESENT(fEGLImageTargetRenderbufferStorage);
-        mSymbols.fEGLImageTargetRenderbufferStorage(target, image);
-        AFTER_GL_CALL;
-    }
-
 #undef ASSERT_SYMBOL_PRESENT
 
 #ifdef DEBUG
     void THEBES_API CreatedProgram(GLContext *aOrigin, GLuint aName);
     void THEBES_API CreatedShader(GLContext *aOrigin, GLuint aName);
     void THEBES_API CreatedBuffers(GLContext *aOrigin, GLsizei aCount, GLuint *aNames);
     void THEBES_API CreatedTextures(GLContext *aOrigin, GLsizei aCount, GLuint *aNames);
     void THEBES_API CreatedFramebuffers(GLContext *aOrigin, GLsizei aCount, GLuint *aNames);
@@ -2899,288 +3123,147 @@ public:
 
         Derived* derived = static_cast<Derived*>(this);
         derived->UnwrapImpl();
 
         mIsUnwrapped = true;
     }
 };
 
+struct ScopedFramebufferTexture
+    : public ScopedGLWrapper<ScopedFramebufferTexture>
+{
+    friend struct ScopedGLWrapper<ScopedFramebufferTexture>;
+
+protected:
+    bool mComplete; // True if the framebuffer we create is complete.
+    GLuint mFB;
+
+public:
+    ScopedFramebufferTexture(GLContext* gl, GLuint texture)
+        : ScopedGLWrapper<ScopedFramebufferTexture>(gl)
+        , mComplete(false)
+        , mFB(0)
+    {
+        MOZ_ASSERT(mGL->IsCurrent());
+        GLuint boundFB = mGL->GetUserBoundFBO();
+
+        mGL->fGenFramebuffers(1, &mFB);
+        mGL->fBindFramebuffer(LOCAL_GL_FRAMEBUFFER, mFB);
+        mGL->fFramebufferTexture2D(LOCAL_GL_FRAMEBUFFER,
+                                   LOCAL_GL_COLOR_ATTACHMENT0,
+                                   LOCAL_GL_TEXTURE_2D,
+                                   texture,
+                                   0);
+
+        GLenum status = mGL->fCheckFramebufferStatus(LOCAL_GL_FRAMEBUFFER);
+        if (status == LOCAL_GL_FRAMEBUFFER_COMPLETE) {
+            mComplete = true;
+        } else {
+            mGL->fDeleteFramebuffers(1, &mFB);
+            mFB = 0;
+        }
+
+        mGL->BindUserFBO(boundFB);
+    }
+
+protected:
+    void UnwrapImpl() {
+        if (!mFB)
+            return;
+
+        MOZ_ASSERT(mGL->IsCurrent());
+        mGL->fDeleteFramebuffers(1, &mFB);
+        mFB = 0;
+    }
+
+public:
+    GLuint FB() const {
+        return mFB;
+    }
+
+    bool IsComplete() const {
+        return mComplete;
+    }
+};
+
 // Wraps glEnable/Disable.
 struct ScopedGLState
     : public ScopedGLWrapper<ScopedGLState>
 {
     friend struct ScopedGLWrapper<ScopedGLState>;
 
 protected:
     const GLenum mCapability;
     bool mOldState;
 
 public:
     // Use |newState = true| to enable, |false| to disable.
     ScopedGLState(GLContext* gl, GLenum capability, bool newState)
         : ScopedGLWrapper<ScopedGLState>(gl)
         , mCapability(capability)
     {
+        MOZ_ASSERT(mGL->IsCurrent());
         mOldState = mGL->fIsEnabled(mCapability);
 
         // Early out if we're already in the right state.
         if (newState == mOldState)
             return;
 
         if (newState)
             mGL->fEnable(mCapability);
         else
             mGL->fDisable(mCapability);
     }
 
 protected:
     void UnwrapImpl() {
+        MOZ_ASSERT(mGL->IsCurrent());
+
         if (mOldState)
             mGL->fEnable(mCapability);
         else
             mGL->fDisable(mCapability);
     }
 };
 
-// Saves and restores with GetUserBoundFB and BindUserFB.
-struct ScopedBindFramebuffer
-    : public ScopedGLWrapper<ScopedBindFramebuffer>
+// Saves and restores with GetUserBoundFBO and BindUserFBO.
+struct ScopedFramebufferBinding
+    : public ScopedGLWrapper<ScopedFramebufferBinding>
 {
-    friend struct ScopedGLWrapper<ScopedBindFramebuffer>;
+    friend struct ScopedGLWrapper<ScopedFramebufferBinding>;
 
 protected:
-    GLuint mOldFB;
-
-private:
-    void Init() {
-        mOldFB = mGL->GetFB();
-    }
-
-public:
-    explicit ScopedBindFramebuffer(GLContext* gl)
-        : ScopedGLWrapper<ScopedBindFramebuffer>(gl)
-    {
-        Init();
-    }
-
-    ScopedBindFramebuffer(GLContext* gl, GLuint newFB)
-        : ScopedGLWrapper<ScopedBindFramebuffer>(gl)
-    {
-        Init();
-        mGL->BindFB(newFB);
-    }
-
-protected:
-    void UnwrapImpl() {
-        // Check that we're not falling out of scope after
-        // the current context changed.
-        MOZ_ASSERT(mGL->IsCurrent());
-
-        mGL->BindFB(mOldFB);
-    }
-};
-
-struct ScopedBindTexture
-    : public ScopedGLWrapper<ScopedBindTexture>
-{
-    friend struct ScopedGLWrapper<ScopedBindTexture>;
-
-protected:
-    GLuint mOldTex;
+    GLuint mOldState;
 
 private:
     void Init() {
-        mOldTex = 0;
-        mGL->GetUIntegerv(LOCAL_GL_TEXTURE_BINDING_2D, &mOldTex);
+        MOZ_ASSERT(mGL->IsCurrent());
+        mOldState = mGL->GetUserBoundFBO();
     }
 
 public:
-    explicit ScopedBindTexture(GLContext* gl)
-        : ScopedGLWrapper<ScopedBindTexture>(gl)
+    ScopedFramebufferBinding(GLContext* gl)
+        : ScopedGLWrapper<ScopedFramebufferBinding>(gl)
     {
         Init();
     }
 
-    ScopedBindTexture(GLContext* gl, GLuint newTex)
-        : ScopedGLWrapper<ScopedBindTexture>(gl)
+    ScopedFramebufferBinding(GLContext* gl, GLuint newFB)
+        : ScopedGLWrapper<ScopedFramebufferBinding>(gl)
     {
         Init();
-        mGL->fBindTexture(LOCAL_GL_TEXTURE_2D, newTex);
-    }
-
-protected:
-    void UnwrapImpl() {
-        // Check that we're not falling out of scope after
-        // the current context changed.
-        MOZ_ASSERT(mGL->IsCurrent());
-
-        mGL->fBindTexture(LOCAL_GL_TEXTURE_2D, mOldTex);
-    }
-};
-
-
-struct ScopedBindRenderbuffer
-    : public ScopedGLWrapper<ScopedBindRenderbuffer>
-{
-    friend struct ScopedGLWrapper<ScopedBindRenderbuffer>;
-
-protected:
-    GLuint mOldRB;
-
-private:
-    void Init() {
-        mOldRB = 0;
-        mGL->GetUIntegerv(LOCAL_GL_RENDERBUFFER_BINDING, &mOldRB);
-    }
-
-public:
-    explicit ScopedBindRenderbuffer(GLContext* gl)
-        : ScopedGLWrapper<ScopedBindRenderbuffer>(gl)
-    {
-        Init();
-    }
-
-    ScopedBindRenderbuffer(GLContext* gl, GLuint newRB)
-        : ScopedGLWrapper<ScopedBindRenderbuffer>(gl)
-    {
-        Init();
-        mGL->fBindRenderbuffer(LOCAL_GL_RENDERBUFFER, newRB);
+        mGL->BindUserFBO(newFB);
     }
 
 protected:
     void UnwrapImpl() {
-        // Check that we're not falling out of scope after
-        // the current context changed.
         MOZ_ASSERT(mGL->IsCurrent());
-
-        mGL->fBindRenderbuffer(LOCAL_GL_RENDERBUFFER, mOldRB);
-    }
-};
-
-struct ScopedFramebufferForTexture
-    : public ScopedGLWrapper<ScopedFramebufferForTexture>
-{
-    friend struct ScopedGLWrapper<ScopedFramebufferForTexture>;
-
-protected:
-    bool mComplete; // True if the framebuffer we create is complete.
-    GLuint mFB;
-
-public:
-    ScopedFramebufferForTexture(GLContext* gl, GLuint texture)
-        : ScopedGLWrapper<ScopedFramebufferForTexture>(gl)
-        , mComplete(false)
-        , mFB(0)
-    {
-        mGL->fGenFramebuffers(1, &mFB);
-        ScopedBindFramebuffer autoFB(gl, mFB);
-        mGL->fFramebufferTexture2D(LOCAL_GL_FRAMEBUFFER,
-                                   LOCAL_GL_COLOR_ATTACHMENT0,
-                                   LOCAL_GL_TEXTURE_2D,
-                                   texture,
-                                   0);
-
-        GLenum status = mGL->fCheckFramebufferStatus(LOCAL_GL_FRAMEBUFFER);
-        if (status == LOCAL_GL_FRAMEBUFFER_COMPLETE) {
-            mComplete = true;
-        } else {
-            mGL->fDeleteFramebuffers(1, &mFB);
-            mFB = 0;
-        }
-    }
-
-protected:
-    void UnwrapImpl() {
-        if (!mFB)
-            return;
-
-        mGL->fDeleteFramebuffers(1, &mFB);
-        mFB = 0;
-    }
-
-public:
-    GLuint FB() const {
-        MOZ_ASSERT(IsComplete());
-        return mFB;
-    }
-
-    bool IsComplete() const {
-        return mComplete;
+        mGL->BindUserFBO(mOldState);
     }
 };
 
-struct ScopedFramebufferForRenderbuffer
-    : public ScopedGLWrapper<ScopedFramebufferForRenderbuffer>
-{
-    friend struct ScopedGLWrapper<ScopedFramebufferForRenderbuffer>;
-
-protected:
-    bool mComplete; // True if the framebuffer we create is complete.
-    GLuint mFB;
-
-public:
-    ScopedFramebufferForRenderbuffer(GLContext* gl, GLuint rb)
-        : ScopedGLWrapper<ScopedFramebufferForRenderbuffer>(gl)
-        , mComplete(false)
-        , mFB(0)
-    {
-        mGL->fGenFramebuffers(1, &mFB);
-        ScopedBindFramebuffer autoFB(gl, mFB);
-        mGL->fFramebufferRenderbuffer(LOCAL_GL_FRAMEBUFFER,
-                                      LOCAL_GL_COLOR_ATTACHMENT0,
-                                      LOCAL_GL_RENDERBUFFER,
-                                      rb);
-
-        GLenum status = mGL->fCheckFramebufferStatus(LOCAL_GL_FRAMEBUFFER);
-        if (status == LOCAL_GL_FRAMEBUFFER_COMPLETE) {
-            mComplete = true;
-        } else {
-            mGL->fDeleteFramebuffers(1, &mFB);
-            mFB = 0;
-        }
-    }
-
-protected:
-    void UnwrapImpl() {
-        if (!mFB)
-            return;
-
-        mGL->fDeleteFramebuffers(1, &mFB);
-        mFB = 0;
-    }
-
-public:
-    GLuint FB() const {
-        return mFB;
-    }
-
-    bool IsComplete() const {
-        return mComplete;
-    }
-};
-
-
-class TextureGarbageBin {
-    NS_INLINE_DECL_THREADSAFE_REFCOUNTING(TextureGarbageBin)
-
-protected:
-    GLContext* mGL;
-    Mutex mMutex;
-    std::stack<GLuint> mGarbageTextures;
-
-public:
-    TextureGarbageBin(GLContext* gl)
-        : mGL(gl)
-        , mMutex("TextureGarbageBin mutex")
-    {}
-
-    void GLContextTeardown();
-    void Trash(GLuint tex);
-    void EmptyGarbage();
-};
-
 uint32_t GetBitsPerTexel(GLenum format, GLenum type);
 
 } /* namespace gl */
 } /* namespace mozilla */
 
 #endif /* GLCONTEXT_H_ */
--- a/gfx/gl/GLContextProvider.h
+++ b/gfx/gl/GLContextProvider.h
@@ -5,17 +5,16 @@
 
 #ifndef GLCONTEXTPROVIDER_H_
 #define GLCONTEXTPROVIDER_H_
 
 #include "GLContext.h"
 #include "gfxTypes.h"
 #include "gfxPoint.h"
 #include "nsAutoPtr.h"
-#include "SurfaceTypes.h"
 
 class nsIWidget;
 class gfxASurface;
 
 namespace mozilla {
 namespace gl {
 
 #define IN_GL_CONTEXT_PROVIDER_H
--- a/gfx/gl/GLContextProviderCGL.mm
+++ b/gfx/gl/GLContextProviderCGL.mm
@@ -13,18 +13,16 @@
 #include "gfxImageSurface.h"
 #include "gfxQuartzSurface.h"
 #include "gfxPlatform.h"
 #include "gfxFailure.h"
 #include "prenv.h"
 #include "mozilla/Preferences.h"
 #include "sampler.h"
 
-using namespace mozilla::gfx;
-
 namespace mozilla {
 namespace gl {
 
 static bool gUseDoubleBufferedWindows = true;
 
 class CGLLibrary
 {
 public:
@@ -81,31 +79,45 @@ private:
 
 CGLLibrary sCGLLibrary;
 
 class GLContextCGL : public GLContext
 {
     friend class GLContextProviderCGL;
 
 public:
-    GLContextCGL(const SurfaceCaps& caps,
-                 GLContext *shareContext,
-                 NSOpenGLContext *context,
-                 bool isOffscreen = false)
-        : GLContext(caps, shareContext, isOffscreen),
-          mContext(context),
+    GLContextCGL(const ContextFormat& aFormat,
+                 GLContext *aShareContext,
+                 NSOpenGLContext *aContext,
+                 bool aIsOffscreen = false)
+        : GLContext(aFormat, aIsOffscreen, aShareContext),
+          mContext(aContext),
+          mPBuffer(nullptr),
           mTempTextureName(0)
-    {}
+    { }
+
+    GLContextCGL(const ContextFormat& aFormat,
+                 GLContext *aShareContext,
+                 NSOpenGLContext *aContext,
+                 NSOpenGLPixelBuffer *aPixelBuffer)
+        : GLContext(aFormat, true, aShareContext),
+          mContext(aContext),
+          mPBuffer(aPixelBuffer),
+          mTempTextureName(0)
+    { }
 
     ~GLContextCGL()
     {
         MarkDestroyed();
 
         if (mContext)
             [mContext release];
+
+        if (mPBuffer)
+            [mPBuffer release];
     }
 
     GLContextType GetContextType() {
         return ContextTypeCGL;
     }
 
     bool Init()
     {
@@ -163,34 +175,122 @@ public:
 
     bool SwapBuffers()
     {
       SAMPLE_LABEL("GLContext", "SwapBuffers");
       [mContext flushBuffer];
       return true;
     }
 
+    bool BindTex2DOffscreen(GLContext *aOffscreen);
+    void UnbindTex2DOffscreen(GLContext *aOffscreen);
     bool ResizeOffscreen(const gfxIntSize& aNewSize);
 
     virtual already_AddRefed<TextureImage>
     CreateBasicTextureImage(GLuint aTexture,
                             const nsIntSize& aSize,
                             GLenum aWrapMode,
                             TextureImage::ContentType aContentType,
                             GLContext* aContext,
                             TextureImage::Flags aFlags = TextureImage::NoFlags);
 
     NSOpenGLContext *mContext;
+    NSOpenGLPixelBuffer *mPBuffer;
     GLuint mTempTextureName;
 };
 
 bool
+GLContextCGL::BindTex2DOffscreen(GLContext *aOffscreen)
+{
+    if (aOffscreen->GetContextType() != ContextTypeCGL) {
+        NS_WARNING("non-CGL context");
+        return false;
+    }
+
+    if (!aOffscreen->IsOffscreen()) {
+        NS_WARNING("non-offscreen context");
+        return false;
+    }
+
+    GLContextCGL *offs = static_cast<GLContextCGL*>(aOffscreen);
+
+    if (offs->mPBuffer) {
+        fGenTextures(1, &mTempTextureName);
+        fBindTexture(LOCAL_GL_TEXTURE_2D, mTempTextureName);
+
+        [mContext
+         setTextureImageToPixelBuffer:offs->mPBuffer
+         colorBuffer:LOCAL_GL_FRONT];
+    } else if (offs->mOffscreenTexture) {
+        if (offs->GetSharedContext() != GLContextProviderCGL::GetGlobalContext())
+        {
+            NS_WARNING("offscreen FBO context can only be bound with context sharing!");
+            return false;
+        }
+
+        fBindTexture(LOCAL_GL_TEXTURE_2D, offs->mOffscreenTexture);
+    } else {
+        NS_WARNING("don't know how to bind this!");
+        return false;
+    }
+
+    return true;
+}
+
+void
+GLContextCGL::UnbindTex2DOffscreen(GLContext *aOffscreen)
+{
+    NS_ASSERTION(aOffscreen->GetContextType() == ContextTypeCGL, "wrong type");
+
+    GLContextCGL *offs = static_cast<GLContextCGL*>(aOffscreen);
+    if (offs->mPBuffer) {
+        NS_ASSERTION(mTempTextureName, "We didn't have an offscreen texture name?");
+        fDeleteTextures(1, &mTempTextureName);
+        mTempTextureName = 0;
+    }
+}
+
+bool
 GLContextCGL::ResizeOffscreen(const gfxIntSize& aNewSize)
 {
-    return ResizeScreenBuffer(aNewSize);
+    if (!IsOffscreenSizeAllowed(aNewSize))
+        return false;
+
+    if (mPBuffer) {
+        NSOpenGLPixelBuffer *pb = [[NSOpenGLPixelBuffer alloc]
+                                   initWithTextureTarget:LOCAL_GL_TEXTURE_2D
+                                   textureInternalFormat:(mCreationFormat.alpha ? LOCAL_GL_RGBA : LOCAL_GL_RGB)
+                                   textureMaxMipMapLevel:0
+                                   pixelsWide:aNewSize.width
+                                   pixelsHigh:aNewSize.height];
+        if (!pb) {
+            return false;
+        }
+
+        if (!ResizeOffscreenFBOs(aNewSize, false)) {
+            [pb release];
+            return false;
+        }
+
+        [mPBuffer release];
+        mPBuffer = pb;
+
+        mOffscreenSize = aNewSize;
+        mOffscreenActualSize = aNewSize;
+
+        [mContext setPixelBuffer:pb cubeMapFace:0 mipMapLevel:0
+         currentVirtualScreen:[mContext currentVirtualScreen]];
+
+        MakeCurrent();
+        ClearSafely();
+
+        return true;
+    }
+
+    return ResizeOffscreenFBOs(aNewSize, true);
 }
 
 class TextureImageCGL : public BasicTextureImage
 {
     friend already_AddRefed<TextureImage>
     GLContextCGL::CreateBasicTextureImage(GLuint,
                                           const nsIntSize&,
                                           GLenum,
@@ -326,29 +426,123 @@ GLContextProviderCGL::CreateForWindow(ns
     NSOpenGLContext *context = [[NSOpenGLContext alloc] 
                                 initWithFormat:sCGLLibrary.PixelFormat()
                                 shareContext:(shareContext ? shareContext->mContext : NULL)];
     if (!context) {
         return nullptr;
     }
 
     // make the context transparent
-    SurfaceCaps caps = SurfaceCaps::ForRGBA();
-    nsRefPtr<GLContextCGL> glContext = new GLContextCGL(caps,
+    nsRefPtr<GLContextCGL> glContext = new GLContextCGL(ContextFormat(ContextFormat::BasicRGB24),
                                                         shareContext,
                                                         context);
     if (!glContext->Init()) {
         return nullptr;
     }
 
     return glContext.forget();
 }
 
 static already_AddRefed<GLContextCGL>
-CreateOffscreenFBOContext(bool aShare = true)
+CreateOffscreenPBufferContext(const gfxIntSize& aSize,
+                              const ContextFormat& aFormat,
+                              bool aShare = false)
+{
+    if (!sCGLLibrary.EnsureInitialized()) {
+        return nullptr;
+    }
+
+    GLContextCGL *shareContext = aShare ? GetGlobalContextCGL() : nullptr;
+    if (aShare && !shareContext) {
+        return nullptr;
+    }
+
+    nsTArray<NSOpenGLPixelFormatAttribute> attribs;
+
+#define A_(_x)  attribs.AppendElement(NSOpenGLPixelFormatAttribute(_x))
+    A_(NSOpenGLPFAAccelerated);
+    A_(NSOpenGLPFAPixelBuffer);
+    A_(NSOpenGLPFAMinimumPolicy);
+
+    A_(NSOpenGLPFAColorSize);
+    A_(aFormat.colorBits());
+
+    A_(NSOpenGLPFAAlphaSize);
+    A_(aFormat.alpha);
+
+    A_(NSOpenGLPFADepthSize);
+    A_(aFormat.depth);
+
+    A_(NSOpenGLPFAStencilSize);
+    A_(aFormat.stencil);
+
+    A_(0);
+#undef A_
+
+    NSOpenGLPixelFormat *pbFormat = [[NSOpenGLPixelFormat alloc]
+                                     initWithAttributes:attribs.Elements()];
+    if (!pbFormat) {
+        return nullptr;
+    }
+
+    // If we ask for any of these to be on/off and we get the opposite, we stop
+    // creating a pbuffer and instead create an FBO.
+    GLint alphaBits, depthBits, stencilBits;
+    [pbFormat getValues: &alphaBits forAttribute: NSOpenGLPFAAlphaSize forVirtualScreen: 0];
+    [pbFormat getValues: &depthBits forAttribute: NSOpenGLPFADepthSize forVirtualScreen: 0];
+    [pbFormat getValues: &stencilBits forAttribute: NSOpenGLPFAStencilSize forVirtualScreen: 0];
+    if ((alphaBits && !aFormat.alpha) || (!alphaBits && aFormat.alpha) ||
+        (depthBits && !aFormat.alpha) || (!depthBits && aFormat.depth) ||
+        (stencilBits && !aFormat.stencil) || (!stencilBits && aFormat.stencil)) 
+    {
+        [pbFormat release];
+        return nullptr;
+    }
+
+    NSOpenGLPixelBuffer *pb = [[NSOpenGLPixelBuffer alloc]
+                               initWithTextureTarget:LOCAL_GL_TEXTURE_2D
+                               textureInternalFormat:(aFormat.alpha ? LOCAL_GL_RGBA : LOCAL_GL_RGB)
+                               textureMaxMipMapLevel:0
+                               pixelsWide:aSize.width
+                               pixelsHigh:aSize.height];
+    if (!pb) {
+        [pbFormat release];
+        return nullptr;
+    }
+
+    NSOpenGLContext *context = [[NSOpenGLContext alloc]
+                                initWithFormat:pbFormat
+                                shareContext:shareContext ? shareContext->mContext : NULL];
+    if (!context) {
+        [pbFormat release];
+        [pb release];
+        return nullptr;
+    }
+
+    [context
+     setPixelBuffer:pb
+     cubeMapFace:0
+     mipMapLevel:0
+     currentVirtualScreen:[context currentVirtualScreen]];
+
+    {
+        GLint l;
+        [pbFormat getValues:&l forAttribute:NSOpenGLPFADepthSize forVirtualScreen:[context currentVirtualScreen]];
+    }
+
+    [pbFormat release];
+
+    nsRefPtr<GLContextCGL> glContext = new GLContextCGL(aFormat, shareContext, context, pb);
+
+    return glContext.forget();
+}
+
+static already_AddRefed<GLContextCGL>
+CreateOffscreenFBOContext(const ContextFormat& aFormat,
+                          bool aShare = true)
 {
     if (!sCGLLibrary.EnsureInitialized()) {
         return nullptr;
     }
 
     GLContextCGL *shareContext = aShare ? GetGlobalContextCGL() : nullptr;
     if (aShare && !shareContext) {
         // if there is no share context, then we can't use FBOs.
@@ -357,31 +551,51 @@ CreateOffscreenFBOContext(bool aShare = 
 
     NSOpenGLContext *context = [[NSOpenGLContext alloc]
                                 initWithFormat:sCGLLibrary.PixelFormat()
                                 shareContext:shareContext ? shareContext->mContext : NULL];
     if (!context) {
         return nullptr;
     }
 
-    SurfaceCaps dummyCaps = SurfaceCaps::Any();
-    nsRefPtr<GLContextCGL> glContext = new GLContextCGL(dummyCaps, shareContext, context, true);
+    nsRefPtr<GLContextCGL> glContext = new GLContextCGL(aFormat, shareContext, context, true);
 
     return glContext.forget();
 }
 
 already_AddRefed<GLContext>
-GLContextProviderCGL::CreateOffscreen(const gfxIntSize& size,
-                                      const SurfaceCaps& caps,
+GLContextProviderCGL::CreateOffscreen(const gfxIntSize& aSize,
+                                      const ContextFormat& aFormat,
                                       const ContextFlags flags)
 {
-    nsRefPtr<GLContextCGL> glContext = CreateOffscreenFBOContext();
+    ContextFormat actualFormat(aFormat);
+
+    nsRefPtr<GLContextCGL> glContext;
+    
+    NS_ENSURE_TRUE(Preferences::GetRootBranch(), nullptr);
+    const bool preferFBOs = Preferences::GetBool("cgl.prefer-fbo", true);
+    if (!preferFBOs)
+    {
+        glContext = CreateOffscreenPBufferContext(aSize, actualFormat);
+        if (glContext &&
+            glContext->Init() &&
+            glContext->ResizeOffscreenFBOs(aSize, false))
+        {
+            glContext->mOffscreenSize = aSize;
+            glContext->mOffscreenActualSize = aSize;
+
+            return glContext.forget();
+        }
+    }
+
+    // try a FBO as second choice
+    glContext = CreateOffscreenFBOContext(actualFormat);
     if (glContext &&
         glContext->Init() &&
-        glContext->InitOffscreen(size, caps))
+        glContext->ResizeOffscreenFBOs(aSize, true))
     {
         return glContext.forget();
     }
 
     // everything failed
     return nullptr;
 }
 
@@ -394,17 +608,18 @@ GLContextProviderCGL::GetGlobalContext(c
         return nullptr;
     }
 
     if (!gGlobalContext) {
         // There are bugs in some older drivers with pbuffers less
         // than 16x16 in size; also 16x16 is POT so that we can do
         // a FBO with it on older video cards.  A FBO context for
         // sharing is preferred since it has no associated target.
-        gGlobalContext = CreateOffscreenFBOContext(false);
+        gGlobalContext = CreateOffscreenFBOContext(ContextFormat(ContextFormat::BasicRGB24),
+                                                   false);
         if (!gGlobalContext || !static_cast<GLContextCGL*>(gGlobalContext.get())->Init()) {
             NS_WARNING("Couldn't init gGlobalContext.");
             gGlobalContext = nullptr;
             return nullptr; 
         }
 
         gGlobalContext->SetIsGlobalSharedContext(true);
     }
--- a/gfx/gl/GLContextProviderEGL.cpp
+++ b/gfx/gl/GLContextProviderEGL.cpp
@@ -30,25 +30,27 @@
 #endif
 
 #if defined(ANDROID)
 /* from widget */
 #if defined(MOZ_WIDGET_ANDROID)
 #include "AndroidBridge.h"
 #include "nsSurfaceTexture.h"
 #endif
-
 #include <android/log.h>
 #define LOG(args...)  __android_log_print(ANDROID_LOG_INFO, "Gonk" , ## args)
 
 # if defined(MOZ_WIDGET_GONK)
 #  include "cutils/properties.h"
 #  include <ui/GraphicBuffer.h>
 
 using namespace android;
+
+# define EGL_NATIVE_BUFFER_ANDROID 0x3140
+
 # endif
 
 #endif
 
 #define GLES2_LIB "libGLESv2.so"
 #define GLES2_LIB2 "libGLESv2.so.2"
 
 #elif defined(XP_WIN)
@@ -125,18 +127,16 @@ static bool gUseBackingSurface = true;
 #else
 static bool gUseBackingSurface = false;
 #endif
 
 #ifdef MOZ_WIDGET_GONK
 extern nsIntRect gScreenBounds;
 #endif
 
-#define EGL_DISPLAY()        sEGLLibrary.Display()
-
 namespace mozilla {
 namespace gl {
 
 static GLLibraryEGL sEGLLibrary;
 
 #define ADD_ATTR_2(_array, _k, _v) do {         \
     (_array).AppendElement(_k);                 \
     (_array).AppendElement(_v);                 \
@@ -196,90 +196,81 @@ is_power_of_two(int v)
     return (v & (v-1)) == 0;
 }
 
 class GLContextEGL : public GLContext
 {
     friend class TextureImageEGL;
 
     static already_AddRefed<GLContextEGL>
-    CreateGLContext(const SurfaceCaps& caps,
+    CreateGLContext(const ContextFormat& format,
+                    EGLSurface surface,
+                    EGLConfig config,
                     GLContextEGL *shareContext,
-                    bool isOffscreen,
-                    EGLConfig config,
-                    EGLSurface surface)
+                    bool aIsOffscreen = false)
     {
-        if (sEGLLibrary.fBindAPI(LOCAL_EGL_OPENGL_ES_API) == LOCAL_EGL_FALSE) {
-            NS_WARNING("Failed to bind API to GLES!");
-            return nullptr;
-        }
-
-        EGLContext eglShareContext = shareContext ? shareContext->mContext
-                                                  : EGL_NO_CONTEXT;
-        EGLint* attribs = sEGLLibrary.HasRobustness() ? gContextAttribsRobustness
-                                                      : gContextAttribs;
-
-        EGLContext context = sEGLLibrary.fCreateContext(EGL_DISPLAY(),
-                                                        config,
-                                                        eglShareContext,
-                                                        attribs);
-        if (!context && shareContext) {
-            shareContext = nullptr;
-            context = sEGLLibrary.fCreateContext(EGL_DISPLAY(),
-                                                 config,
-                                                 EGL_NO_CONTEXT,
-                                                 attribs);
-            if (!context) {
-                NS_WARNING("Failed to create EGLContext!");
-                return nullptr;
+        EGLContext context;
+
+        context = sEGLLibrary.fCreateContext(EGL_DISPLAY(),
+                                             config,
+                                             shareContext ? shareContext->mContext : EGL_NO_CONTEXT,
+                                             sEGLLibrary.HasRobustness() ? gContextAttribsRobustness
+                                                                         : gContextAttribs);
+        if (!context) {
+            if (shareContext) {
+                shareContext = nullptr;
+                context = sEGLLibrary.fCreateContext(EGL_DISPLAY(),
+                                                     config,
+                                                     EGL_NO_CONTEXT,
+                                                     sEGLLibrary.HasRobustness() ? gContextAttribsRobustness
+                                                                                 : gContextAttribs);
+                if (!context) {
+                    NS_WARNING("Failed to create EGLContext!");
+                    return nullptr;
+                }
             }
         }
 
-        nsRefPtr<GLContextEGL> glContext = new GLContextEGL(caps,
-                                                            shareContext,
-                                                            isOffscreen,
-                                                            config,
-                                                            surface,
-                                                            context);
+        nsRefPtr<GLContextEGL> glContext =
+            new GLContextEGL(format, shareContext, config,
+                             surface, context, aIsOffscreen);
 
         if (!glContext->Init())
             return nullptr;
 
         return glContext.forget();
     }
 
 public:
-    GLContextEGL(const SurfaceCaps& caps,
-                 GLContext* shareContext,
-                 bool isOffscreen,
-                 EGLConfig config,
-                 EGLSurface surface,
-                 EGLContext context)
-        : GLContext(caps, shareContext, isOffscreen)
-        , mConfig(config)
-        , mSurface(surface)
-        , mCurSurface(surface)
-        , mContext(context)
+    GLContextEGL(const ContextFormat& aFormat,
+                 GLContext *aShareContext,
+                 EGLConfig aConfig,
+                 EGLSurface aSurface,
+                 EGLContext aContext,
+                 bool aIsOffscreen = false)
+        : GLContext(aFormat, aIsOffscreen, aShareContext)
+        , mConfig(aConfig) 
+        , mSurface(aSurface), mContext(aContext)
         , mPlatformContext(nullptr)
         , mThebesSurface(nullptr)
         , mBound(false)
         , mIsPBuffer(false)
         , mIsDoubleBuffered(false)
         , mCanBindToTexture(false)
         , mShareWithEGLImage(false)
         , mTemporaryEGLImageTexture(0)
     {
         // any EGL contexts will always be GLESv2
         SetIsGLES2(true);
 
 #ifdef DEBUG
         printf_stderr("Initializing context %p surface %p on display %p\n", mContext, mSurface, EGL_DISPLAY());
 #endif
 #ifdef MOZ_WIDGET_GONK
-        if (!mIsOffscreen) {
+        if (!aIsOffscreen) {
             mHwc = HwcComposer2D::GetInstance();
             MOZ_ASSERT(!mHwc->Initialized());
 
             if (mHwc->Init(EGL_DISPLAY(), mSurface)) {
                 NS_WARNING("HWComposer initialization failed!");
                 mHwc = nullptr;
             }
         }
@@ -367,25 +358,16 @@ public:
     bool IsDoubleBuffered() {
         return mIsDoubleBuffered;
     }
 
     void SetIsDoubleBuffered(bool aIsDB) {
         mIsDoubleBuffered = aIsDB;
     }
 
-    virtual EGLContext GetEGLContext() {
-        return mContext;
-    }
-
-    virtual GLLibraryEGL* GetLibraryEGL() {
-        return &sEGLLibrary;
-    }
-
-
     bool SupportsRobustness()
     {
         return sEGLLibrary.HasRobustness();
     }
 
     virtual bool IsANGLE()
     {
         return sEGLLibrary.IsANGLE();
@@ -431,17 +413,17 @@ public:
     {
 #if defined(MOZ_WIDGET_GONK)
         EGLint attrs[] = {
             LOCAL_EGL_IMAGE_PRESERVED, LOCAL_EGL_TRUE,
             LOCAL_EGL_NONE, LOCAL_EGL_NONE
         };
         EGLImage image = sEGLLibrary.fCreateImage(EGL_DISPLAY(),
                                                   EGL_NO_CONTEXT,
-                                                  LOCAL_EGL_NATIVE_BUFFER_ANDROID,
+                                                  EGL_NATIVE_BUFFER_ANDROID,
                                                   buffer, attrs);
         fBindTexture(LOCAL_GL_TEXTURE_EXTERNAL, texture);
         fEGLImageTargetTexture2D(LOCAL_GL_TEXTURE_EXTERNAL, image);
         sEGLLibrary.fDestroyImage(EGL_DISPLAY(), image);
         return true;
 #else
         return false;
 #endif
@@ -463,29 +445,16 @@ public:
 #endif
     }
 
 #ifdef MOZ_WIDGET_GONK
     virtual already_AddRefed<TextureImage>
     CreateDirectTextureImage(GraphicBuffer* aBuffer, GLenum aWrapMode) MOZ_OVERRIDE;
 #endif
 
-    virtual void MakeCurrent_EGLSurface(void* surf) {
-        EGLSurface eglSurface = (EGLSurface)surf;
-        if (!eglSurface)
-            eglSurface = mSurface;
-
-        if (eglSurface == mCurSurface)
-            return;
-
-        // Else, surface changed...
-        mCurSurface = eglSurface;
-        MakeCurrent(true);
-    }
-
     bool MakeCurrentImpl(bool aForce = false) {
         bool succeeded = true;
 
         // Assume that EGL has the same problem as WGL does,
         // where MakeCurrent with an already-current context is
         // still expensive.
 #ifndef MOZ_WIDGET_QT
         if (!mSurface) {
@@ -509,17 +478,17 @@ public:
             if (mSharedContext) {
                 QGLContext* qglCtx = static_cast<QGLContext*>(static_cast<GLContextEGL*>(mSharedContext.get())->mPlatformContext);
                 if (qglCtx) {
                     qglCtx->doneCurrent();
                 }
             }
 #endif
             succeeded = sEGLLibrary.fMakeCurrent(EGL_DISPLAY(),
-                                                 mCurSurface, mCurSurface,
+                                                 mSurface, mSurface,
                                                  mContext);
             
             int eglError = sEGLLibrary.fGetError();
             if (!succeeded) {
                 if (eglError == LOCAL_EGL_CONTEXT_LOST) {
                     mContextLost = true;
                     NS_WARNING("EGL context has been lost.");
                 } else {
@@ -635,20 +604,51 @@ public:
     }
 
     bool BindTex2DOffscreen(GLContext *aOffscreen);
     void UnbindTex2DOffscreen(GLContext *aOffscreen);
     bool ResizeOffscreen(const gfxIntSize& aNewSize);
     void BindOffscreenFramebuffer();
 
     static already_AddRefed<GLContextEGL>
-    CreateEGLPixmapOffscreenContext(const gfxIntSize& size);
+    CreateEGLPixmapOffscreenContext(const gfxIntSize& aSize,
+                                    const ContextFormat& aFormat,
+                                    bool aShare);
 
     static already_AddRefed<GLContextEGL>
-    CreateEGLPBufferOffscreenContext(const gfxIntSize& size);
+    CreateEGLPBufferOffscreenContext(const gfxIntSize& aSize,
+                                     const ContextFormat& aFormat,
+                                     bool bufferUnused = false);
+
+    void SetOffscreenSize(const gfxIntSize &aRequestedSize,
+                          const gfxIntSize &aActualSize)
+    {
+        mOffscreenSize = aRequestedSize;
+        mOffscreenActualSize = aActualSize;
+    }
+
+    void *GetD3DShareHandle() {
+        if (!sEGLLibrary.HasANGLESurfaceD3DTexture2DShareHandle()) {
+            return nullptr;
+        }
+
+        void *h = nullptr;
+
+#ifndef EGL_D3D_TEXTURE_2D_SHARE_HANDLE_ANGLE
+#define EGL_D3D_TEXTURE_2D_SHARE_HANDLE_ANGLE 0x3200
+#endif
+
+        if (!sEGLLibrary.fQuerySurfacePointerANGLE(EGL_DISPLAY(), mSurface,
+                                                   EGL_D3D_TEXTURE_2D_SHARE_HANDLE_ANGLE, (void**) &h))
+        {
+            return nullptr;
+        }
+
+        return h;
+    }
 
     virtual bool HasLockSurface() {
         return sEGLLibrary.HasKHRLockSurface();
     }
 
     virtual SharedTextureHandle CreateSharedHandle(SharedTextureShareType shareType);
     virtual SharedTextureHandle CreateSharedHandle(SharedTextureShareType shareType,
                                                    void* buffer,
@@ -657,23 +657,21 @@ public:
                                     SharedTextureHandle sharedHandle);
     virtual void ReleaseSharedHandle(SharedTextureShareType shareType,
                                      SharedTextureHandle sharedHandle);
     virtual bool GetSharedHandleDetails(SharedTextureShareType shareType,
                                         SharedTextureHandle sharedHandle,
                                         SharedHandleDetails& details);
     virtual bool AttachSharedHandle(SharedTextureShareType shareType,
                                     SharedTextureHandle sharedHandle);
-
 protected:
     friend class GLContextProviderEGL;
 
     EGLConfig  mConfig;
     EGLSurface mSurface;
-    EGLSurface mCurSurface;
     EGLContext mContext;
     void *mPlatformContext;
     nsRefPtr<gfxASurface> mThebesSurface;
     bool mBound;
 
     bool mIsPBuffer;
     bool mIsDoubleBuffered;
     bool mCanBindToTexture;
@@ -725,17 +723,16 @@ protected:
             NS_WARNING("Failed to create pbuffer surface");
             return nullptr;
         }
 
         return surface;
     }
 };
 
-
 typedef enum {
     Image
 #ifdef MOZ_WIDGET_ANDROID
     , SurfaceTexture
 #endif
 } SharedHandleType;
 
 class SharedTextureHandleWrapper
@@ -789,18 +786,17 @@ public:
     // Args are the active GL context, and a texture in that GL
     // context for which to create an EGLImage.  After the EGLImage
     // is created, the texture is unused by EGLTextureWrapper.
     bool CreateEGLImage(GLContextEGL *ctx, GLuint texture) {
         MOZ_ASSERT(!mEGLImage && texture && sEGLLibrary.HasKHRImageBase());
         static const EGLint eglAttributes[] = {
             LOCAL_EGL_NONE
         };
-        EGLContext eglContext = (EGLContext)ctx->GetEGLContext();
-        mEGLImage = sEGLLibrary.fCreateImage(EGL_DISPLAY(), eglContext, LOCAL_EGL_GL_TEXTURE_2D,
+        mEGLImage = sEGLLibrary.fCreateImage(EGL_DISPLAY(), ctx->Context(), LOCAL_EGL_GL_TEXTURE_2D,
                                              (EGLClientBuffer)texture, eglAttributes);
         if (!mEGLImage) {
 #ifdef DEBUG
             printf_stderr("Could not create EGL images: ERROR (0x%04x)\n", sEGLLibrary.fGetError());
 #endif
             return false;
         }
         return true;
@@ -873,24 +869,32 @@ GLContextEGL::UpdateSharedHandle(SharedT
 
     NS_ASSERTION(wrapper->Type() == SharedHandleType::Image, "Expected EGLImage shared handle");
     NS_ASSERTION(mShareWithEGLImage, "EGLImage not supported or disabled in runtime");
 
     EGLTextureWrapper* wrap = reinterpret_cast<EGLTextureWrapper*>(wrapper);
     // We need to copy the current GLContext drawing buffer to the texture
     // exported by the EGLImage.  Need to save both the read FBO and the texture
     // binding, because we're going to munge them to do this.
-    ScopedBindTexture autoTex(this, mTemporaryEGLImageTexture);
+    GLuint prevRead = GetUserBoundReadFBO();
+    GLint oldtex = -1;
+    BindUserReadFBO(0);
+    fGetIntegerv(LOCAL_GL_TEXTURE_BINDING_2D, &oldtex);
+    MOZ_ASSERT(oldtex != -1);
+    fBindTexture(LOCAL_GL_TEXTURE_2D, mTemporaryEGLImageTexture);
     fEGLImageTargetTexture2D(LOCAL_GL_TEXTURE_2D, wrap->GetEGLImage());
 
-    // CopyTexSubImage2D, is ~2x slower than simple FBO render to texture with
-    // draw quads, but if we want that, we need to assure that our default
-    // framebuffer is texture-backed.
-    gfxIntSize size = OffscreenSize();
-    BlitFramebufferToTexture(0, mTemporaryEGLImageTexture, size, size);
+    // CopyTexSubImage2D, is ~2x slower than simple FBO render to texture with draw quads,
+    // but render with draw quads require complex and hard to maintain context save/restore code
+    fCopyTexSubImage2D(LOCAL_GL_TEXTURE_2D, 0, 0, 0,
+                       0, 0, mOffscreenActualSize.width,
+                       mOffscreenActualSize.height);
+
+    fBindTexture(LOCAL_GL_TEXTURE_2D, oldtex);
+    BindUserReadFBO(prevRead);
 
     // Make sure our copy is finished, so that we can be ready to draw
     // in different thread GLContext.  If we have KHR_fence_sync, then
     // we insert a sync object, otherwise we have to do a GuaranteeResolve.
     wrap->MakeSync(this);
 }
 
 SharedTextureHandle
@@ -898,17 +902,20 @@ GLContextEGL::CreateSharedHandle(SharedT
 {
     if (shareType != SameProcess)
         return 0;
 
     if (!mShareWithEGLImage)
         return 0;
 
     MakeCurrent();
-    mTemporaryEGLImageTexture = CreateTextureForOffscreen(GetGLFormats(), OffscreenSize());
+    ContextFormat fmt = ActualFormat();
+
+    CreateTextureForOffscreen(ChooseGLFormats(fmt, GLContext::ForceRGBA), mOffscreenActualSize,
+                              mTemporaryEGLImageTexture);
 
     EGLTextureWrapper* tex = new EGLTextureWrapper();
     bool ok = tex->CreateEGLImage(this, mTemporaryEGLImageTexture);
 
     if (!ok) {
         NS_ERROR("EGLImage creation for EGLTextureWrapper failed");
         ReleaseSharedHandle(shareType, (SharedTextureHandle)tex);
         return 0;
@@ -918,17 +925,17 @@ GLContextEGL::CreateSharedHandle(SharedT
     return (SharedTextureHandle)tex;
 }
 
 SharedTextureHandle
 GLContextEGL::CreateSharedHandle(SharedTextureShareType shareType,
                                  void* buffer,
                                  SharedTextureBufferType bufferType)
 {
-    // Both EGLImage and SurfaceTexture only support same-process currently, but
+    // Both EGLImage and SurfaceTexture only support ThreadShared currently, but
     // it's possible to make SurfaceTexture work across processes. We should do that.
     if (shareType != SameProcess)
         return 0;
 
     switch (bufferType) {
 #ifdef MOZ_WIDGET_ANDROID
     case SharedTextureBufferType::SurfaceTexture:
         if (!IsExtensionSupported(GLContext::OES_EGL_image_external)) {
@@ -1045,17 +1052,17 @@ bool GLContextEGL::AttachSharedHandle(Sh
 
         // FIXME: SurfaceTexture provides a transform matrix which is supposed to
         // be applied to the texture coordinates. We should return that here
         // so we can render correctly. Bug 775083
         surfaceTextureWrapper->SurfaceTexture()->UpdateTexImage();
         break;
     }
 #endif // MOZ_WIDGET_ANDROID
-
+    
     case SharedHandleType::Image: {
         NS_ASSERTION(mShareWithEGLImage, "EGLImage not supported or disabled in runtime");
 
         EGLTextureWrapper* wrap = (EGLTextureWrapper*)sharedHandle;
         wrap->WaitSync();
         fEGLImageTargetTexture2D(LOCAL_GL_TEXTURE_2D, wrap->GetEGLImage());
         break;
     }
@@ -1063,20 +1070,104 @@ bool GLContextEGL::AttachSharedHandle(Sh
     default:
         NS_ERROR("Unknown shared handle type");
         return false;
     }
 
     return true;
 }
 
+
+bool
+GLContextEGL::BindTex2DOffscreen(GLContext *aOffscreen)
+{
+    if (aOffscreen->GetContextType() != ContextTypeEGL) {
+        NS_WARNING("non-EGL context");
+        return false;
+    }
+
+    GLContextEGL *offs = static_cast<GLContextEGL*>(aOffscreen);
+
+    if (offs->mCanBindToTexture) {
+        bool ok = sEGLLibrary.fBindTexImage(EGL_DISPLAY(),
+                                              offs->mSurface,
+                                              LOCAL_EGL_BACK_BUFFER);
+        return ok;
+    }
+
+    if (offs->mOffscreenTexture) {
+        if (offs->GetSharedContext() != GLContextProviderEGL::GetGlobalContext())
+        {
+            NS_WARNING("offscreen FBO context can only be bound with context sharing!");
+            return false;
+        }
+
+        fBindTexture(LOCAL_GL_TEXTURE_2D, offs->mOffscreenTexture);
+        return true;
+    }
+
+    NS_WARNING("don't know how to bind this!");
+
+    return false;
+}
+
+void
+GLContextEGL::UnbindTex2DOffscreen(GLContext *aOffscreen)
+{
+    NS_ASSERTION(aOffscreen->GetContextType() == ContextTypeEGL, "wrong type");
+
+    GLContextEGL *offs = static_cast<GLContextEGL*>(aOffscreen);
+
+    if (offs->mCanBindToTexture) {
+        sEGLLibrary.fReleaseTexImage(EGL_DISPLAY(),
+                                     offs->mSurface,
+                                     LOCAL_EGL_BACK_BUFFER);
+    }
+}
+
 bool
 GLContextEGL::ResizeOffscreen(const gfxIntSize& aNewSize)
 {
-	return ResizeScreenBuffer(aNewSize);
+    if (!IsOffscreenSizeAllowed(aNewSize))
+        return false;
+
+    if (mIsPBuffer) {
+        gfxIntSize pbsize(aNewSize);
+
+        EGLSurface surface =
+            CreatePBufferSurfaceTryingPowerOfTwo(mConfig,
+                                                 mCanBindToTexture
+                                                 ? (mCreationFormat.minAlpha
+                                                    ? LOCAL_EGL_TEXTURE_RGBA
+                                                    : LOCAL_EGL_TEXTURE_RGB)
+                                                 : LOCAL_EGL_NONE,
+                                                 pbsize);
+        if (!surface) {
+            NS_WARNING("Failed to resize pbuffer");
+            return false;
+        }
+
+        if (!ResizeOffscreenFBOs(pbsize, false))
+            return false;
+
+        SetOffscreenSize(aNewSize, pbsize);
+
+        if (mSurface && !mPlatformContext) {
+            sEGLLibrary.fDestroySurface(EGL_DISPLAY(), mSurface);
+        }
+
+        mSurface = surface;
+
+        MakeCurrent(true);
+        ClearSafely();
+
+        return true;
+    }
+
+    return ResizeOffscreenFBOs(aNewSize, true);
 }
 
 
 static GLContextEGL *
 GetGlobalContextEGL()
 {
     return static_cast<GLContextEGL*>(GLContextProviderEGL::GetGlobalContext());
 }
@@ -1738,17 +1829,17 @@ public:
                              GraphicBuffer::USAGE_SW_READ_OFTEN |
                              GraphicBuffer::USAGE_SW_WRITE_OFTEN;
             mGraphicBuffer = new GraphicBuffer(aSize.width, aSize.height, format, usage);
             if (mGraphicBuffer->initCheck() == OK) {
                 const int eglImageAttributes[] = { LOCAL_EGL_IMAGE_PRESERVED, LOCAL_EGL_TRUE,
                                                    LOCAL_EGL_NONE, LOCAL_EGL_NONE };
                 mEGLImage = sEGLLibrary.fCreateImage(EGL_DISPLAY(),
                                                         EGL_NO_CONTEXT,
-                                                        LOCAL_EGL_NATIVE_BUFFER_ANDROID,
+                                                        EGL_NATIVE_BUFFER_ANDROID,
                                                         (EGLClientBuffer) mGraphicBuffer->getNativeBuffer(),
                                                         eglImageAttributes);
                 if (!mEGLImage) {
                     mGraphicBuffer = nullptr;
                     LOG("Could not create EGL images: ERROR (0x%04x)", sEGLLibrary.fGetError());
                     return false;
                 }
 
@@ -1812,17 +1903,17 @@ public:
         mGraphicBuffer = aGraphicBuffer;
 
         const int eglImageAttributes[] =
             { LOCAL_EGL_IMAGE_PRESERVED, LOCAL_EGL_TRUE,
               LOCAL_EGL_NONE, LOCAL_EGL_NONE };
 
         mEGLImage = sEGLLibrary.fCreateImage(EGL_DISPLAY(),
                                              EGL_NO_CONTEXT,
-                                             LOCAL_EGL_NATIVE_BUFFER_ANDROID,
+                                             EGL_NATIVE_BUFFER_ANDROID,
                                              mGraphicBuffer->getNativeBuffer(),
                                              eglImageAttributes);
         if (!mEGLImage) {
             LOG("Could not create EGL images: ERROR (0x%04x)", sEGLLibrary.fGetError());
         }
     }
 };
 
@@ -1881,41 +1972,50 @@ GLContextEGL::TileGenFunc(const nsIntSiz
   fTexParameteri(LOCAL_GL_TEXTURE_2D, LOCAL_GL_TEXTURE_MIN_FILTER, texfilter);
   fTexParameteri(LOCAL_GL_TEXTURE_2D, LOCAL_GL_TEXTURE_MAG_FILTER, texfilter);
   fTexParameteri(LOCAL_GL_TEXTURE_2D, LOCAL_GL_TEXTURE_WRAP_S, LOCAL_GL_CLAMP_TO_EDGE);
   fTexParameteri(LOCAL_GL_TEXTURE_2D, LOCAL_GL_TEXTURE_WRAP_T, LOCAL_GL_CLAMP_TO_EDGE);
 
   return teximage.forget();
 }
 
+inline static ContextFormat
+DepthToGLFormat(int aDepth)
+{
+    switch (aDepth) {
+        case 32:
+            return ContextFormat::BasicRGBA32;
+        case 24:
+            return ContextFormat::BasicRGB24;
+        case 16:
+            return ContextFormat::BasicRGB16_565;
+        default:
+            break;
+    }
+    return ContextFormat::BasicRGBA32;
+}
+
 static nsRefPtr<GLContext> gGlobalContext;
 
-static const EGLint kEGLConfigAttribsOffscreenPBuffer[] = {
-    LOCAL_EGL_SURFACE_TYPE,    LOCAL_EGL_PBUFFER_BIT,
-    LOCAL_EGL_RENDERABLE_TYPE, LOCAL_EGL_OPENGL_ES2_BIT,
-    LOCAL_EGL_NONE
-};
-
 static const EGLint kEGLConfigAttribsRGB16[] = {
     LOCAL_EGL_SURFACE_TYPE,    LOCAL_EGL_WINDOW_BIT,
     LOCAL_EGL_RENDERABLE_TYPE, LOCAL_EGL_OPENGL_ES2_BIT,
     LOCAL_EGL_RED_SIZE,        5,
     LOCAL_EGL_GREEN_SIZE,      6,
     LOCAL_EGL_BLUE_SIZE,       5,
     LOCAL_EGL_ALPHA_SIZE,      0,
     LOCAL_EGL_NONE
 };
 
 static const EGLint kEGLConfigAttribsRGB24[] = {
     LOCAL_EGL_SURFACE_TYPE,    LOCAL_EGL_WINDOW_BIT,
     LOCAL_EGL_RENDERABLE_TYPE, LOCAL_EGL_OPENGL_ES2_BIT,
     LOCAL_EGL_RED_SIZE,        8,
     LOCAL_EGL_GREEN_SIZE,      8,
     LOCAL_EGL_BLUE_SIZE,       8,
-    LOCAL_EGL_ALPHA_SIZE,      0,
     LOCAL_EGL_NONE
 };
 
 static const EGLint kEGLConfigAttribsRGBA32[] = {
     LOCAL_EGL_SURFACE_TYPE,    LOCAL_EGL_WINDOW_BIT,
     LOCAL_EGL_RENDERABLE_TYPE, LOCAL_EGL_OPENGL_ES2_BIT,
     LOCAL_EGL_RED_SIZE,        8,
     LOCAL_EGL_GREEN_SIZE,      8,
@@ -2023,144 +2123,285 @@ CreateSurfaceForWindow(nsIWidget *aWidge
 
     return surface;
 }
 #endif
 
 already_AddRefed<GLContext>
 GLContextProviderEGL::CreateForWindow(nsIWidget *aWidget)
 {
+    EGLConfig config;
+
     if (!sEGLLibrary.EnsureInitialized()) {
         return nullptr;
     }
 
     bool doubleBuffered = true;
 
-    EGLContext eglContext = sEGLLibrary.fGetCurrentContext();
-    if (aWidget->HasGLContext() && eglContext) {
-        //int colorDepth = gfxPlatform::GetPlatform()->GetScreenDepth();
-        void* platformContext = eglContext;
+    void* currentContext = sEGLLibrary.fGetCurrentContext();
+    if (aWidget->HasGLContext() && currentContext) {
+        int32_t depth = gfxPlatform::GetPlatform()->GetScreenDepth();
+        void* platformContext = currentContext;
 #ifdef MOZ_WIDGET_QT
         QGLContext* context = const_cast<QGLContext*>(QGLContext::currentContext());
         if (context && context->device()) {
             depth = context->device()->depth();
         }
         doubleBuffered = context->format().doubleBuffer();
         platformContext = context;
 #endif
-
-        SurfaceCaps caps = SurfaceCaps::Any();
-        EGLConfig config = EGL_NO_CONFIG;
-        EGLSurface surface = sEGLLibrary.fGetCurrentSurface(LOCAL_EGL_DRAW);
         nsRefPtr<GLContextEGL> glContext =
-            new GLContextEGL(caps,
-                             gGlobalContext, false,
-                             config, surface, eglContext);
+            new GLContextEGL(ContextFormat(DepthToGLFormat(depth)),
+                             gGlobalContext,
+                             NULL,
+                             sEGLLibrary.fGetCurrentSurface(LOCAL_EGL_DRAW), // just use same surface for read and draw
+                             currentContext,
+                             false);
 
         if (!glContext->Init())
             return nullptr;
 
         glContext->MakeCurrent();
+        sEGLLibrary.LoadConfigSensitiveSymbols();
+
         glContext->SetIsDoubleBuffered(doubleBuffered);
+
         glContext->SetPlatformContext(platformContext);
-
         if (!gGlobalContext) {
             gGlobalContext = glContext;
         }
 
         return glContext.forget();
     }
 
-    EGLConfig config;
     if (!CreateConfig(&config)) {
         printf_stderr("Failed to create EGL config!\n");
         return nullptr;
     }
 
 #ifdef MOZ_ANDROID_OMTC
     mozilla::AndroidBridge::Bridge()->RegisterCompositor();
     EGLSurface surface = mozilla::AndroidBridge::Bridge()->ProvideEGLSurface(true);
 #else
     EGLSurface surface = CreateSurfaceForWindow(aWidget, config);
 #endif
 
     if (!surface) {
-        printf_stderr("Failed to create EGLSurface!\n");
+        return nullptr;
+    }
+
+    if (!sEGLLibrary.fBindAPI(LOCAL_EGL_OPENGL_ES_API)) {
+        sEGLLibrary.fDestroySurface(EGL_DISPLAY(), surface);
         return nullptr;
     }
 
-    GLContextEGL* shareContext = GetGlobalContextEGL();
-    SurfaceCaps caps = SurfaceCaps::Any();
+    GLContextEGL *shareContext = GetGlobalContextEGL();
+
     nsRefPtr<GLContextEGL> glContext =
-        GLContextEGL::CreateGLContext(caps,
-                                      shareContext, false,
-                                      config, surface);
+        GLContextEGL::CreateGLContext(ContextFormat(ContextFormat::BasicRGB24),
+                                      surface,
+                                      config,
+                                      shareContext,
+                                      false);
 
     if (!glContext) {
-        sEGLLibrary.fDestroySurface(EGL_DISPLAY(), surface);
         return nullptr;
     }
 
     glContext->MakeCurrent();
+    sEGLLibrary.LoadConfigSensitiveSymbols();
     glContext->SetIsDoubleBuffered(doubleBuffered);
 
     return glContext.forget();
 }
 
+static void
+FillPBufferAttribs_Minimal(nsTArray<EGLint>& aAttrs)
+{
+    aAttrs.Clear();
+
+#define A1(_x)      do { aAttrs.AppendElement(_x); } while (0)
+#define A2(_x,_y)   do { A1(_x); A1(_y); } while (0)
+
+    A2(LOCAL_EGL_RENDERABLE_TYPE, LOCAL_EGL_OPENGL_ES2_BIT);
+
+    A2(LOCAL_EGL_SURFACE_TYPE, LOCAL_EGL_PBUFFER_BIT);
+
+    A1(LOCAL_EGL_NONE);
+#undef A1
+#undef A2
+}
+
+static void
+FillPBufferAttribs(nsTArray<EGLint>& aAttrs,
+                   const ContextFormat& aFormat,
+                   bool aCanBindToTexture,
+                   int aColorBitsOverride,
+                   int aDepthBitsOverride)
+{
+    aAttrs.Clear();
+
+#define A1(_x)      do { aAttrs.AppendElement(_x); } while (0)
+#define A2(_x,_y)   do { A1(_x); A1(_y); } while (0)
+
+    A2(LOCAL_EGL_RENDERABLE_TYPE, LOCAL_EGL_OPENGL_ES2_BIT);
+
+    A2(LOCAL_EGL_SURFACE_TYPE, LOCAL_EGL_PBUFFER_BIT);
+
+    if (aColorBitsOverride == -1) {
+        A2(LOCAL_EGL_RED_SIZE, aFormat.red);
+        A2(LOCAL_EGL_GREEN_SIZE, aFormat.green);
+        A2(LOCAL_EGL_BLUE_SIZE, aFormat.blue);
+    } else {
+        A2(LOCAL_EGL_RED_SIZE, aColorBitsOverride);
+        A2(LOCAL_EGL_GREEN_SIZE, aColorBitsOverride);
+        A2(LOCAL_EGL_BLUE_SIZE, aColorBitsOverride);
+    }
+
+    A2(LOCAL_EGL_ALPHA_SIZE, aFormat.alpha);
+
+    if (aDepthBitsOverride == -1) {
+        A2(LOCAL_EGL_DEPTH_SIZE, aFormat.minDepth);
+    } else {
+        A2(LOCAL_EGL_DEPTH_SIZE, aDepthBitsOverride);
+    }
+
+    A2(LOCAL_EGL_STENCIL_SIZE, aFormat.minStencil);
+
+    if (aCanBindToTexture) {
+        A2(aFormat.minAlpha ? LOCAL_EGL_BIND_TO_TEXTURE_RGBA : LOCAL_EGL_BIND_TO_TEXTURE_RGB,
+           LOCAL_EGL_TRUE);
+    }
+
+    A1(LOCAL_EGL_NONE);
+#undef A1
+#undef A2
+}
+
 already_AddRefed<GLContextEGL>
-GLContextEGL::CreateEGLPBufferOffscreenContext(const gfxIntSize& size)
+GLContextEGL::CreateEGLPBufferOffscreenContext(const gfxIntSize& aSize,
+                                               const ContextFormat& aFormat,
+                                               bool bufferUnused)
 {
     EGLConfig config;
     EGLSurface surface;
-
-    const EGLint numConfigs = 1; // We only need one.
-    EGLConfig configs[numConfigs];
-    EGLint foundConfigs = 0;
+    EGLContext context;
+
+    bool configCanBindToTexture = true;
+
+    EGLConfig configs[64];
+    int numConfigs = sizeof(configs)/sizeof(EGLConfig);
+    int foundConfigs = 0;
+
+    // if we're running under ANGLE, we can't set BIND_TO_TEXTURE --
+    // it's not supported, and we have dx interop pbuffers anyway
+    if (sEGLLibrary.IsANGLE() || bufferUnused)
+        configCanBindToTexture = false;
+
+    nsTArray<EGLint> attribs(32);
+    int attribAttempt = 0;
+
+    int tryDepthSize = (aFormat.depth > 0) ? 24 : 0;
+
+TRY_ATTRIBS_AGAIN:
+    if (bufferUnused) {
+        FillPBufferAttribs_Minimal(attribs);
+    } else {
+        switch (attribAttempt) {
+        case 0:
+            FillPBufferAttribs(attribs, aFormat, configCanBindToTexture, 8, tryDepthSize);
+            break;
+        case 1:
+            FillPBufferAttribs(attribs, aFormat, configCanBindToTexture, -1, tryDepthSize);
+            break;
+        case 2:
+            FillPBufferAttribs(attribs, aFormat, configCanBindToTexture, -1, -1);
+            break;
+        }
+    }
+
     if (!sEGLLibrary.fChooseConfig(EGL_DISPLAY(),
-                                   kEGLConfigAttribsOffscreenPBuffer,
+                                   &attribs[0],
                                    configs, numConfigs,
                                    &foundConfigs)
         || foundConfigs == 0)
     {
-        NS_WARNING("No EGL Config for minimal PBuffer!");
+        if (bufferUnused) {
+            NS_WARNING("No EGL Config for minimal PBuffer!");
+            return nullptr;
+        }
+
+        if (attribAttempt < 3) {
+            attribAttempt++;
+            goto TRY_ATTRIBS_AGAIN;
+        }
+
+        if (configCanBindToTexture) {
+            NS_WARNING("No pbuffer EGL configs that can bind to texture, trying without");
+            configCanBindToTexture = false;
+            attribAttempt = 0;
+            goto TRY_ATTRIBS_AGAIN;
+        }
+
+        // no configs? no pbuffers!
+        NS_WARNING("Failed to select acceptable config for PBuffer creation!");
         return nullptr;
     }
 
-    // We absolutely don't care, so just pick the first one.
+    // XXX do some smarter matching here, perhaps instead of the more complex
+    // minimum overrides above
     config = configs[0];
-    if (GLContext::DebugMode())
-        sEGLLibrary.DumpEGLConfig(config);
-
-    gfxIntSize pbSize(size);
+#ifdef DEBUG
+    sEGLLibrary.DumpEGLConfig(config);
+#endif
+
+    gfxIntSize pbsize(aSize);
     surface = GLContextEGL::CreatePBufferSurfaceTryingPowerOfTwo(config,
-                                                                 LOCAL_EGL_NONE,
-                                                                 pbSize);
+                                                                 configCanBindToTexture
+                                                                 ? (aFormat.minAlpha
+                                                                    ? LOCAL_EGL_TEXTURE_RGBA
+                                                                    : LOCAL_EGL_TEXTURE_RGB)
+                                                                 : LOCAL_EGL_NONE,
+                                                                 pbsize);
     if (!surface) {
         NS_WARNING("Failed to create PBuffer for context!");
         return nullptr;
     }
 
+    sEGLLibrary.fBindAPI(LOCAL_EGL_OPENGL_ES_API);
+
     GLContextEGL* shareContext = GetGlobalContextEGL();
-    SurfaceCaps dummyCaps = SurfaceCaps::Any();
-    nsRefPtr<GLContextEGL> glContext =
-        GLContextEGL::CreateGLContext(dummyCaps,
-                                      shareContext, true,
-                                      config, surface);
-    if (!glContext) {
+    context = sEGLLibrary.fCreateContext(EGL_DISPLAY(),
+                                         config,
+                                         shareContext ? shareContext->mContext
+                                                      : EGL_NO_CONTEXT,
+                                         sEGLLibrary.HasRobustness() ? gContextAttribsRobustness
+                                                                     : gContextAttribs);
+    if (!context) { 
         NS_WARNING("Failed to create GLContext from PBuffer");
         sEGLLibrary.fDestroySurface(EGL_DISPLAY(), surface);
         return nullptr;
     }
 
+    nsRefPtr<GLContextEGL> glContext = new GLContextEGL(aFormat, shareContext,
+                                                        config, surface, context,
+                                                        true);
+
     if (!glContext->Init()) {
         NS_WARNING("Failed to initialize GLContext!");
-        // GLContextEGL::dtor will destroy |surface| for us.
         return nullptr;
     }
 
+    glContext->mCanBindToTexture = configCanBindToTexture;
+
+    if (!bufferUnused) {  // We *are* using the buffer
+      glContext->SetOffscreenSize(aSize, pbsize);
+      glContext->mIsPBuffer = true;
+    }
+
     return glContext.forget();
 }
 
 #ifdef MOZ_X11
 EGLSurface
 CreateEGLSurfaceForXSurface(gfxASurface* aSurface, EGLConfig* aConfig)
 {
     gfxXlibSurface* xsurface = static_cast<gfxXlibSurface*>(aSurface);
@@ -2244,27 +2485,29 @@ CreateEGLSurfaceForXSurface(gfxASurface*
     if (aConfig)
         *aConfig = configs[i];
 
     return surface;
 }
 #endif
 
 already_AddRefed<GLContextEGL>
-GLContextEGL::CreateEGLPixmapOffscreenContext(const gfxIntSize& size)
+GLContextEGL::CreateEGLPixmapOffscreenContext(const gfxIntSize& aSize,
+                                              const ContextFormat& aFormat,
+                                              bool aShare)
 {
     gfxASurface *thebesSurface = nullptr;
     EGLNativePixmapType pixmap = 0;
 
 #ifdef MOZ_X11
     nsRefPtr<gfxXlibSurface> xsurface =
         gfxXlibSurface::Create(DefaultScreenOfDisplay(DefaultXDisplay()),
                                gfxXlibSurface::FindRenderFormat(DefaultXDisplay(),
                                                                 gfxASurface::ImageFormatRGB24),
-                               size);
+                               aSize);
 
     // XSync required after gfxXlibSurface::Create, otherwise EGL will fail with BadDrawable error
     XSync(DefaultXDisplay(), False);
     if (xsurface->CairoStatus() != 0)
         return nullptr;
 
     thebesSurface = xsurface;
     pixmap = (EGLNativePixmapType)xsurface->XDrawable();
@@ -2278,72 +2521,79 @@ GLContextEGL::CreateEGLPixmapOffscreenCo
     EGLConfig config = 0;
 
 #ifdef MOZ_X11
     surface = CreateEGLSurfaceForXSurface(thebesSurface, &config);
 #endif
     if (!config) {
         return nullptr;
     }
-    MOZ_ASSERT(surface);
-
-    GLContextEGL* shareContext = GetGlobalContextEGL();
-    SurfaceCaps dummyCaps = SurfaceCaps::Any();
+
+    GLContextEGL *shareContext = aShare ? GetGlobalContextEGL() : nullptr;
+
     nsRefPtr<GLContextEGL> glContext =
-    GLContextEGL::CreateGLContext(dummyCaps,
-                                  shareContext, true,
-                                  surface, config);
-    if (!glContext) {
-        NS_WARNING("Failed to create GLContext from XSurface");
-        sEGLLibrary.fDestroySurface(EGL_DISPLAY(), surface);
-        return nullptr;
-    }
-
-    if (!glContext->Init()) {
-        NS_WARNING("Failed to initialize GLContext!");
-        // GLContextEGL::dtor will destroy |surface| for us.
-        return nullptr;
-    }
+        GLContextEGL::CreateGLContext(aFormat,
+                                      surface,
+                                      config,
+                                      shareContext,
+                                      true);
 
     glContext->HoldSurface(thebesSurface);
 
     return glContext.forget();
 }
 
 // Under EGL, if we're under X11, then we have to create a Pixmap
 // because Maemo's EGL implementation doesn't support pbuffers at all
 // for some reason.  On Android, pbuffers are supported fine, though
 // often without the ability to texture from them directly.
 already_AddRefed<GLContext>
-GLContextProviderEGL::CreateOffscreen(const gfxIntSize& size,
-                                      const SurfaceCaps& caps,
-                                      ContextFlags flags)
+GLContextProviderEGL::CreateOffscreen(const gfxIntSize& aSize,
+                                      const ContextFormat& aFormat,
+                                      const ContextFlags aFlags)
 {
     if (!sEGLLibrary.EnsureInitialized()) {
         return nullptr;
     }
 
-    gfxIntSize dummySize = gfxIntSize(16, 16);
-    nsRefPtr<GLContextEGL> glContext;
-#if defined(MOZ_X11)
-    glContext = GLContextEGL::CreateEGLPixmapOffscreenContext(dummySize);
-#else
-    glContext = GLContextEGL::CreateEGLPBufferOffscreenContext(dummySize);
-#endif
+#if !defined(MOZ_X11)
+    bool usePBuffers = false; // Generally, prefer FBOs to PBuffers
+
+    if (sEGLLibrary.IsANGLE())
+      usePBuffers = true; // For d3d share handle, we need an EGL surface
+
+    gfxIntSize pbufferSize = usePBuffers ? aSize : gfxIntSize(16, 16);
+    nsRefPtr<GLContextEGL> glContext =
+        GLContextEGL::CreateEGLPBufferOffscreenContext(pbufferSize, aFormat, !usePBuffers);
 
     if (!glContext)
         return nullptr;
 
-    if (flags & GLContext::ContextFlagsGlobal)
-        return glContext.forget();
-
-    if (!glContext->InitOffscreen(size, caps))
+    gfxIntSize fboSize = usePBuffers ? glContext->OffscreenActualSize() : aSize;
+    if (!(aFlags & GLContext::ContextFlagsGlobal) && !glContext->ResizeOffscreenFBOs(fboSize, !usePBuffers))
         return nullptr;
 
     return glContext.forget();
+#elif defined(MOZ_X11)
+    nsRefPtr<GLContextEGL> glContext =
+        GLContextEGL::CreateEGLPixmapOffscreenContext(gfxIntSize(16, 16), aFormat, true);
+
+    if (!glContext) {
+        return nullptr;
+    }
+
+    if (!(aFlags & GLContext::ContextFlagsGlobal) && !glContext->ResizeOffscreenFBOs(aSize, true)) {
+        // we weren't able to create the initial
+        // offscreen FBO, so this is dead
+        return nullptr;
+    }
+    return glContext.forget();
+#else
+    return nullptr;
+#endif
 }
 
 // Don't want a global context on Android as 1) share groups across 2 threads fail on many Tegra drivers (bug 759225)
 // and 2) some mobile devices have a very strict limit on global number of GL contexts (bug 754257)
 // and 3) each EGL context eats 750k on B2G (bug 813783)
 GLContext *
 GLContextProviderEGL::GetGlobalContext(const ContextFlags)
 {
--- a/gfx/gl/GLContextProviderGLX.cpp
+++ b/gfx/gl/GLContextProviderGLX.cpp
@@ -31,18 +31,16 @@
 #include "gfxUtils.h"
 
 #include "gfxCrashReporterUtils.h"
 
 #ifdef MOZ_WIDGET_GTK
 #include "gfxPlatformGtk.h"
 #endif
 
-using namespace mozilla::gfx;
-
 namespace mozilla {
 namespace gl {
 
 GLXLibrary sGLXLibrary[GLXLibrary::LIBS_MAX];
 GLXLibrary& sDefGLXLib = sGLXLibrary[GLXLibrary::OPENGL_LIB];
 
 typedef GLXLibrary::LibraryType LibType;
 
@@ -67,55 +65,41 @@ GLXLibrary::GLXVersionCheck(int aMajor, 
 static inline bool
 HasExtension(const char* aExtensions, const char* aRequiredExtension)
 {
     return GLContext::ListHasExtension(
         reinterpret_cast<const GLubyte*>(aExtensions), aRequiredExtension);
 }
 
 bool
-GLXLibrary::EnsureInitialized(LibType libType)
+GLXLibrary::EnsureInitialized(bool aUseMesaLLVMPipe)
 {
     if (mInitialized) {
         return true;
     }
 
     // Don't repeatedly try to initialize.
     if (mTriedInitializing) {
         return false;
     }
     mTriedInitializing = true;
 
-    // Force enabling s3 texture compression. (Bug 774134)
+    // Force enabling s3 texture compression (http://dri.freedesktop.org/wiki/S3TC)
     PR_SetEnv("force_s3tc_enable=true");
 
     if (!mOGLLibrary) {
-        const char* libGLfilename = nullptr;
-        bool forceFeatureReport = false;
-        switch (libType) {
-        case MESA_LLVMPIPE_LIB:
-            libGLfilename = "mesallvmpipe.so";
-            forceFeatureReport = true;
-            break;
-        case OPENGL_LIB:
-            // see e.g. bug 608526: it is intrinsically interesting to know whether we have dynamically linked to libGL.so.1
-            // because at least the NVIDIA implementation requires an executable stack, which causes mprotect calls,
-            // which trigger glibc bug http://sourceware.org/bugzilla/show_bug.cgi?id=12225
+        // see e.g. bug 608526: it is intrinsically interesting to know whether we have dynamically linked to libGL.so.1
+        // because at least the NVIDIA implementation requires an executable stack, which causes mprotect calls,
+        // which trigger glibc bug http://sourceware.org/bugzilla/show_bug.cgi?id=12225
 #ifdef __OpenBSD__
-            libGLfilename = "libGL.so";
+        const char *libGLfilename = aUseMesaLLVMPipe? "mesallvmpipe.so" : "libGL.so";
 #else
-            libGLfilename = "libGL.so.1";
+        const char *libGLfilename = aUseMesaLLVMPipe? "mesallvmpipe.so" : "libGL.so.1";
 #endif
-            break;
-        default:
-            MOZ_NOT_REACHED("Invalid GLX library type.");
-            return false;
-        }
-
-        ScopedGfxFeatureReporter reporter(libGLfilename, forceFeatureReport);
+        ScopedGfxFeatureReporter reporter(libGLfilename, aUseMesaLLVMPipe);
         mOGLLibrary = PR_LoadLibrary(libGLfilename);
         if (!mOGLLibrary) {
             NS_WARNING("Couldn't load OpenGL shared library.");
             return false;
         }
         reporter.SetSuccessful();
     }
 
@@ -261,25 +245,26 @@ GLXLibrary::EnsureInitialized(LibType li
         GLLibraryLoader::LoadSymbols(mOGLLibrary, symbols_robustness)) {
         mHasRobustness = true;
     }
 
     mIsATI = serverVendor && DoesStringMatch(serverVendor, "ATI");
     mClientIsMesa = clientVendor && DoesStringMatch(clientVendor, "Mesa");
 
     mInitialized = true;
-    mLibType = libType;
+    if(aUseMesaLLVMPipe)
+      mLibType = GLXLibrary::MESA_LLVMPIPE_LIB;
 
     return true;
 }
 
 bool
 GLXLibrary::SupportsTextureFromPixmap(gfxASurface* aSurface)
 {
-    if (!EnsureInitialized(mLibType)) {
+    if (!EnsureInitialized(mLibType == MESA_LLVMPIPE_LIB)) {
         return false;
     }
     
     if (aSurface->GetType() != gfxASurface::SurfaceTypeXlib || !mUseTextureFromPixmap) {
         return false;
     }
 
     return true;
@@ -736,31 +721,28 @@ GLXLibrary::xCreateContextAttribs(Displa
     AFTER_GLX_CALL;
     return result;
 }
 
 class GLContextGLX : public GLContext
 {
 public:
     static already_AddRefed<GLContextGLX>
-    CreateGLContext(const SurfaceCaps& caps,
-                    GLContextGLX* shareContext,
-                    bool isOffscreen,
-                    Display* display,
+    CreateGLContext(const ContextFormat& format,
+                    Display *display,
                     GLXDrawable drawable,
                     GLXFBConfig cfg,
+                    GLContextGLX *shareContext,
                     bool deleteDrawable,
-                    LibType libType = GLXLibrary::OPENGL_LIB,
-                    gfxXlibSurface* pixmap = nullptr)
+                    LibType lib = GLXLibrary::OPENGL_LIB,
+                    gfxXlibSurface *pixmap = nullptr)
     {
-        GLXLibrary& glx = sGLXLibrary[libType];
-
-        int db = 0;
-        int err = glx.xGetFBConfigAttrib(display, cfg,
-                                         GLX_DOUBLEBUFFER, &db);
+        int db = 0, err;
+        err = sGLXLibrary[lib].xGetFBConfigAttrib(display, cfg,
+                                             GLX_DOUBLEBUFFER, &db);
         if (GLX_BAD_ATTRIBUTE != err) {
 #ifdef DEBUG
             if (DebugMode()) {
                 printf("[GLX] FBConfig is %sdouble-buffered\n", db ? "" : "not ");
             }
 #endif
         }
 
@@ -769,50 +751,46 @@ public:
         bool error;
 
         ScopedXErrorHandler xErrorHandler;
 
 TRY_AGAIN_NO_SHARING:
 
         error = false;
 
-        GLXContext glxContext = shareContext ? shareContext->mContext : NULL;
-        if (glx.HasRobustness()) {
+        if (sGLXLibrary[lib].HasRobustness()) {
             int attrib_list[] = {
                 LOCAL_GL_CONTEXT_FLAGS_ARB, LOCAL_GL_CONTEXT_ROBUST_ACCESS_BIT_ARB,
                 LOCAL_GL_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB, LOCAL_GL_LOSE_CONTEXT_ON_RESET_ARB,
                 0,
             };
 
-            context = glx.xCreateContextAttribs(
-                display,
-                cfg,
-                glxContext,
-                True,
-                attrib_list);
+            context = sGLXLibrary[lib].xCreateContextAttribs(display,
+                                                        cfg,
+                                                        shareContext ? shareContext->mContext : NULL,
+                                                        True,
+                                                        attrib_list);
         } else {
-            context = glx.xCreateNewContext(
-                display,
-                cfg,
-                GLX_RGBA_TYPE,
-                glxContext,
-                True);
+            context = sGLXLibrary[lib].xCreateNewContext(display,
+                                                    cfg,
+                                                    GLX_RGBA_TYPE,
+                                                    shareContext ? shareContext->mContext : NULL,
+                                                    True);
         }
 
         if (context) {
-            glContext = new GLContextGLX(caps,
-                                         shareContext,
-                                         isOffscreen,
-                                         display,
-                                         drawable,
-                                         context,
-                                         deleteDrawable,
-                                         db,
-                                         pixmap,
-                                         libType);
+            glContext = new GLContextGLX(format,
+                                        shareContext,
+                                        display,
+                                        drawable,
+                                        context,
+                                        deleteDrawable,
+                                        db,
+                                        pixmap,
+                                        lib);
             if (!glContext->Init())
                 error = true;
         } else {
             error = true;
         }
 
         error |= xErrorHandler.SyncAndGetError(display);
 
@@ -833,24 +811,24 @@ TRY_AGAIN_NO_SHARING:
     ~GLContextGLX()
     {
         MarkDestroyed();
 
         // see bug 659842 comment 76
 #ifdef DEBUG
         bool success =
 #endif
-        mGLX->xMakeCurrent(mDisplay, None, nullptr);
+        sGLXLib.xMakeCurrent(mDisplay, None, nullptr);
         NS_ABORT_IF_FALSE(success,
             "glXMakeCurrent failed to release GL context before we call glXDestroyContext!");
 
-        mGLX->xDestroyContext(mDisplay, mContext);
+        sGLXLib.xDestroyContext(mDisplay, mContext);
 
         if (mDeleteDrawable) {
-            mGLX->xDestroyPixmap(mDisplay, mDrawable);
+            sGLXLib.xDestroyPixmap(mDisplay, mDrawable);
         }
     }
 
     GLContextType GetContextType() {
         return ContextTypeGLX;
     }
 
     bool Init()
@@ -874,26 +852,26 @@ TRY_AGAIN_NO_SHARING:
         bool succeeded = true;
 
         // With the ATI FGLRX driver, glxMakeCurrent is very slow even when the context doesn't change.
         // (This is not the case with other drivers such as NVIDIA).
         // So avoid calling it more than necessary. Since GLX documentation says that:
         //     "glXGetCurrentContext returns client-side information.
         //      It does not make a round trip to the server."
         // I assume that it's not worth using our own TLS slot here.
-        if (aForce || mGLX->xGetCurrentContext() != mContext) {
-            succeeded = mGLX->xMakeCurrent(mDisplay, mDrawable, mContext);
+        if (aForce || sGLXLib.xGetCurrentContext() != mContext) {
+            succeeded = sGLXLib.xMakeCurrent(mDisplay, mDrawable, mContext);
             NS_ASSERTION(succeeded, "Failed to make GL context current!");
         }
 
         return succeeded;
     }
 
     virtual bool IsCurrent() {
-        return mGLX->xGetCurrentContext() == mContext;
+        return sGLXLib.xGetCurrentContext() == mContext;
     }
 
     bool SetupLookupFunction()
     {
         mLookupFunc = (PlatformLookupFunction)&GLXLibrary::xGetProcAddress;
         return true;
     }
 
@@ -913,75 +891,72 @@ TRY_AGAIN_NO_SHARING:
 
     bool IsDoubleBuffered()
     {
         return mDoubleBuffered;
     }
 
     bool SupportsRobustness()
     {
-        return mGLX->HasRobustness();
+        return sGLXLib.HasRobustness();
     }
 
     bool SwapBuffers()
     {
         if (!mDoubleBuffered)
             return false;
-        mGLX->xSwapBuffers(mDisplay, mDrawable);
-        mGLX->xWaitGL();
+        sGLXLib.xSwapBuffers(mDisplay, mDrawable);
+        sGLXLib.xWaitGL();
         return true;
     }
 
     bool TextureImageSupportsGetBackingSurface()
     {
-        return mGLX->UseTextureFromPixmap();
+        return sGLXLib.UseTextureFromPixmap();
     }
 
     virtual already_AddRefed<TextureImage>
     CreateTextureImage(const nsIntSize& aSize,
                        TextureImage::ContentType aContentType,
                        GLenum aWrapMode,
                        TextureImage::Flags aFlags = TextureImage::NoFlags);
 
 private:
     friend class GLContextProviderGLX;
 
-    GLContextGLX(const SurfaceCaps& caps,
-                 GLContext* shareContext,
-                 bool isOffscreen,
+    GLContextGLX(const ContextFormat& aFormat,
+                 GLContext *aShareContext,
                  Display *aDisplay,
                  GLXDrawable aDrawable,
                  GLXContext aContext,
                  bool aDeleteDrawable,
                  bool aDoubleBuffered,
                  gfxXlibSurface *aPixmap,
-                 LibType libType)
-        : GLContext(caps, shareContext, isOffscreen),//aDeleteDrawable ? true : false, aShareContext, ),
+                 LibType aLibType)
+        : GLContext(aFormat, aDeleteDrawable ? true : false, aShareContext),
           mContext(aContext),
           mDisplay(aDisplay),
           mDrawable(aDrawable),
           mDeleteDrawable(aDeleteDrawable),
           mDoubleBuffered(aDoubleBuffered),
-          mLibType(libType),
-          mGLX(&sGLXLibrary[libType]),
-          mPixmap(aPixmap)
+          mLibType(aLibType),
+          mPixmap(aPixmap),
+          sGLXLib(sGLXLibrary[aLibType])
     {
-        MOZ_ASSERT(mGLX);
     }
 
     GLXContext mContext;
     Display *mDisplay;
     GLXDrawable mDrawable;
     bool mDeleteDrawable;
     bool mDoubleBuffered;
-
     LibType mLibType;
-    GLXLibrary* mGLX;
 
     nsRefPtr<gfxXlibSurface> mPixmap;
+    GLXLibrary& sGLXLib;
 };
 
 class TextureImageGLX : public TextureImage
 {
     friend already_AddRefed<TextureImage>
     GLContextGLX::CreateTextureImage(const nsIntSize&,
                                      ContentType,
                                      GLenum,
@@ -1110,17 +1085,17 @@ GLContextGLX::CreateTextureImage(const n
 
     if (aContentType == gfxASurface::CONTENT_COLOR_ALPHA) {
         nsRefPtr<gfxContext> ctx = new gfxContext(surface);
         ctx->SetOperator(gfxContext::OPERATOR_CLEAR);
         ctx->Paint();
     }
 
     MakeCurrent();
-    GLXPixmap pixmap = mGLX->CreatePixmap(surface);
+    GLXPixmap pixmap = sGLXLib.CreatePixmap(surface);
     NS_ASSERTION(pixmap, "Failed to create pixmap!");
 
     GLuint texture;
     fGenTextures(1, &texture);
 
     fActiveTexture(LOCAL_GL_TEXTURE0);
     fBindTexture(LOCAL_GL_TEXTURE_2D, texture);
 
@@ -1161,18 +1136,17 @@ AreCompatibleVisuals(Visual *one, Visual
     }
 
     return true;
 }
 
 already_AddRefed<GLContext>
 GLContextProviderGLX::CreateForWindow(nsIWidget *aWidget)
 {
-    const LibType libType = GLXLibrary::OPENGL_LIB;
-    if (!sDefGLXLib.EnsureInitialized(libType)) {
+    if (!sDefGLXLib.EnsureInitialized(false)) {
         return nullptr;
     }
 
     // Currently, we take whatever Visual the window already has, and
     // try to create an fbconfig for that visual.  This isn't
     // necessarily what we want in the long run; an fbconfig may not
     // be available for the existing visual, or if it is, the GL
     // performance might be suboptimal.  But using the existing visual
@@ -1246,71 +1220,77 @@ GLContextProviderGLX::CreateForWindow(ns
 
     if (matchIndex == -1) {
         NS_WARNING("[GLX] Couldn't find a FBConfig matching widget visual");
         return nullptr;
     }
 
     GLContextGLX *shareContext = GetGlobalContextGLX();
 
-    SurfaceCaps caps = SurfaceCaps::Any();
-    nsRefPtr<GLContextGLX> glContext = GLContextGLX::CreateGLContext(caps,
-                                                                     shareContext,
-                                                                     false,
+    nsRefPtr<GLContextGLX> glContext = GLContextGLX::CreateGLContext(ContextFormat(ContextFormat::BasicRGB24),
                                                                      display,
                                                                      window,
                                                                      cfgs[matchIndex],
+                                                                     shareContext,
                                                                      false,
-                                                                     libType);
+                                                                     GLXLibrary::OPENGL_LIB);
 
     return glContext.forget();
 }
 
 static already_AddRefed<GLContextGLX>
-CreateOffscreenPixmapContext(const gfxIntSize& size, LibType libToUse)
+CreateOffscreenPixmapContext(const gfxIntSize& aSize,
+                             const ContextFormat& aFormat,
+                             bool aShare, LibType aLibToUse)
 {
-    GLXLibrary& glx = sGLXLibrary[libToUse];
-    if (!glx.EnsureInitialized(libToUse)) {
+    GLXLibrary& sGLXLib = sGLXLibrary[aLibToUse];
+    if (!sGLXLib.EnsureInitialized(aLibToUse == GLXLibrary::MESA_LLVMPIPE_LIB)) {
         return nullptr;
     }
 
     Display *display = DefaultXDisplay();
     int xscreen = DefaultScreen(display);
 
     int attribs[] = {
+        GLX_DOUBLEBUFFER, False,
         GLX_DRAWABLE_TYPE, GLX_PIXMAP_BIT,
         GLX_X_RENDERABLE, True,
+        GLX_RED_SIZE, 1,
+        GLX_GREEN_SIZE, 1,
+        GLX_BLUE_SIZE, 1,
+        GLX_ALPHA_SIZE, 0,
+        GLX_DEPTH_SIZE, 0,
         0
     };
     int numConfigs = 0;
 
     ScopedXFree<GLXFBConfig> cfgs;
-    cfgs = glx.xChooseFBConfig(display,
-                               xscreen,
-                               attribs,
-                               &numConfigs);
+    cfgs = sGLXLib.xChooseFBConfig(display,
+                                   xscreen,
+                                   attribs,
+                                   &numConfigs);
     if (!cfgs) {
         return nullptr;
     }
 
-    MOZ_ASSERT(numConfigs > 0,
-               "glXChooseFBConfig() failed to match our requested format and violated its spec!");
+    NS_ASSERTION(numConfigs > 0,
+                 "glXChooseFBConfig() failed to match our requested format and violated its spec (!)");
 
     int visid = None;
     int chosenIndex = 0;
 
     for (int i = 0; i < numConfigs; ++i) {
         int dtype;
 
-        if (glx.xGetFBConfigAttrib(display, cfgs[i], GLX_DRAWABLE_TYPE, &dtype) != Success
+        if (sGLXLib.xGetFBConfigAttrib(display, cfgs[i], GLX_DRAWABLE_TYPE, &dtype) != Success
             || !(dtype & GLX_PIXMAP_BIT))
         {
             continue;
         }
-        if (glx.xGetFBConfigAttrib(display, cfgs[i], GLX_VISUAL_ID, &visid) != Success
+        if (sGLXLib.xGetFBConfigAttrib(display, cfgs[i], GLX_VISUAL_ID, &visid) != Success
             || visid == 0)
         {
             continue;
         }
 
         chosenIndex = i;
         break;
     }
@@ -1322,110 +1302,112 @@ CreateOffscreenPixmapContext(const gfxIn
 
     Visual *visual;
     int depth;
     FindVisualAndDepth(display, visid, &visual, &depth);
     ScopedXErrorHandler xErrorHandler;
     GLXPixmap glxpixmap = 0;
     bool error = false;
 
-    gfxIntSize dummySize(16, 16);
     nsRefPtr<gfxXlibSurface> xsurface = gfxXlibSurface::Create(DefaultScreenOfDisplay(display),
                                                                visual,
-                                                               dummySize);
+                                                               gfxIntSize(16, 16));
     if (xsurface->CairoStatus() != 0) {
         error = true;
         goto DONE_CREATING_PIXMAP;
     }
 
     // Handle slightly different signature between glXCreatePixmap and
     // its pre-GLX-1.3 extension equivalent (though given the ABI, we
     // might not need to).
-    if (glx.GLXVersionCheck(1, 3)) {
-        glxpixmap = glx.xCreatePixmap(display,
+    if (sGLXLib.GLXVersionCheck(1, 3)) {
+        glxpixmap = sGLXLib.xCreatePixmap(display,
                                           cfgs[chosenIndex],
                                           xsurface->XDrawable(),
                                           NULL);
     } else {
-        glxpixmap = glx.xCreateGLXPixmapWithConfig(display,
+        glxpixmap = sGLXLib.xCreateGLXPixmapWithConfig(display,
                                                        cfgs[chosenIndex],
                                                        xsurface->
                                                        XDrawable());
     }
     if (glxpixmap == 0) {
         error = true;
     }
 
 DONE_CREATING_PIXMAP:
 
     nsRefPtr<GLContextGLX> glContext;
     bool serverError = xErrorHandler.SyncAndGetError(display);
 
     if (!error && // earlier recorded error
         !serverError)
     {
-        GLContext::ContextFlags flag = libToUse == GLXLibrary::MESA_LLVMPIPE_LIB
-                                         ? GLContext::ContextFlagsMesaLLVMPipe
-                                         : GLContext::ContextFlagsNone;
-        // We might have an alpha channel, but it doesn't matter.
-        SurfaceCaps dummyCaps = SurfaceCaps::Any();
-        GLContextGLX* shareContext = GetGlobalContextGLX(flag);
-
-        glContext = GLContextGLX::CreateGLContext(dummyCaps,
-                                                  shareContext,
-                                                  true,
-                                                  display,
-                                                  glxpixmap,
-                                                  cfgs[chosenIndex],
-                                                  false,
-                                                  libToUse,
-                                                  xsurface);
+      GLContext::ContextFlags flag = aLibToUse == GLXLibrary::OPENGL_LIB
+                                       ? GLContext::ContextFlagsNone
+                                       : GLContext::ContextFlagsMesaLLVMPipe;
+        glContext = GLContextGLX::CreateGLContext(
+                        aFormat,
+                        display,
+                        glxpixmap,
+                        cfgs[chosenIndex],
+                        aShare ? GetGlobalContextGLX(flag) : nullptr,
+                        true,
+                        aLibToUse,
+                        xsurface);
     }
 
     return glContext.forget();
 }
 
 already_AddRefed<GLContext>
-GLContextProviderGLX::CreateOffscreen(const gfxIntSize& size,
-                                      const SurfaceCaps& caps,
-                                      ContextFlags flags)
+GLContextProviderGLX::CreateOffscreen(const gfxIntSize& aSize,
+                                      const ContextFormat& aFormat,
+                                      const ContextFlags aFlag)
 {
-    LibType libType = GLXLibrary::SelectLibrary(flags);
-    gCurrLib = libType;
+    gCurrLib = GLXLibrary::SelectLibrary(aFlag);
+    nsRefPtr<GLContextGLX> glContext =
+        CreateOffscreenPixmapContext(aSize, aFormat, true, gCurrLib);
+
+    if (!glContext) {
+        return nullptr;
+    }
 
-    gfxIntSize dummySize = gfxIntSize(16, 16);
-    nsRefPtr<GLContextGLX> glContext =
-        CreateOffscreenPixmapContext(dummySize, libType);
+    if (!glContext->GetSharedContext()) {
+        // no point in returning anything if sharing failed, we can't
+        // render from this
+        return nullptr;
+    }
 
-    if (!glContext)
+    if (!glContext->ResizeOffscreenFBOs(aSize, true)) {
+        // we weren't able to create the initial
+        // offscreen FBO, so this is dead
         return nullptr;
-
-    if (!glContext->InitOffscreen(size, caps))
-        return nullptr;
+    }
 
     return glContext.forget();
 }
 
 static nsRefPtr<GLContext> gGlobalContext[GLXLibrary::LIBS_MAX];
 
-GLContext*
+GLContext *
 GLContextProviderGLX::GetGlobalContext(const ContextFlags aFlag)
 {
-    LibType libType = GLXLibrary::SelectLibrary(aFlag);
+    LibType libToUse = GLXLibrary::SelectLibrary(aFlag);
     static bool triedToCreateContext[GLXLibrary::LIBS_MAX] = {false, false};
-    if (!triedToCreateContext[libType] && !gGlobalContext[libType]) {
-        triedToCreateContext[libType] = true;
-
-        gfxIntSize dummySize = gfxIntSize(16, 16);
-        gGlobalContext[libType] = CreateOffscreenPixmapContext(dummySize, libType);
-        if (gGlobalContext[libType])
-            gGlobalContext[libType]->SetIsGlobalSharedContext(true);
+    if (!triedToCreateContext[libToUse] && !gGlobalContext[libToUse]) {
+        triedToCreateContext[libToUse] = true;
+        gGlobalContext[libToUse] = CreateOffscreenPixmapContext(gfxIntSize(1, 1),
+                                                      ContextFormat(ContextFormat::BasicRGB24),
+                                                      false, libToUse);
+        if (gGlobalContext[libToUse])
+            gGlobalContext[libToUse]->SetIsGlobalSharedContext(true);
     }
 
-    return gGlobalContext[libType];
+    return gGlobalContext[libToUse];
 }
 
 void
 GLContextProviderGLX::Shutdown()
 {
     for (int i = 0; i < GLXLibrary::LIBS_MAX; ++i)
       gGlobalContext[i] = nullptr;
 }
--- a/gfx/gl/GLContextProviderImpl.h
+++ b/gfx/gl/GLContextProviderImpl.h
@@ -10,17 +10,16 @@
 #ifndef GL_CONTEXT_PROVIDER_NAME
 #error GL_CONTEXT_PROVIDER_NAME not defined
 #endif
 
 class THEBES_API GL_CONTEXT_PROVIDER_NAME
 {
 public:
     typedef GLContext::ContextFlags ContextFlags;
-    typedef gfx::SurfaceCaps SurfaceCaps;
     /**
      * Create a context that renders to the surface of the widget that is
      * passed in.  The context is always created with an RGB pixel format,
      * with no alpha, depth or stencil.  If any of those features are needed,
      * either use a framebuffer, or use CreateOffscreen.
      *
      * This context will attempt to share resources with all other window
      * contexts.  As such, it's critical that resources allocated that are not
@@ -33,45 +32,46 @@ public:
      * reference to the widget; otherwise a cycle can be created through
      * a GL layer manager.
      *
      * @param aWidget Widget whose surface to create a context for
      *
      * @return Context to use for the window
      */
     static already_AddRefed<GLContext>
-    CreateForWindow(nsIWidget* widget);
+    CreateForWindow(nsIWidget *aWidget);
 
     /**
      * Create a context for offscreen rendering.  The target of this
      * context should be treated as opaque -- it might be a FBO, or a
      * pbuffer, or some other construct.  Users of this GLContext
-     * should bind framebuffer 0 directly to use this offscreen buffer.
+     * should not bind framebuffer 0 directly, and instead should bind
+     * the framebuffer returned by GetOffscreenFBO().
      *
      * The offscreen context returned by this method will always have
      * the ability to be rendered into a context created by a window.
      * It might or might not share resources with the global context;
      * query GetSharedContext() for a non-null result to check.  If
      * resource sharing can be avoided on the target platform, it will
      * be, in order to isolate the offscreen context.
      *
      * @param aSize The initial size of this offscreen context.
      * @param aFormat The ContextFormat for this offscreen context.
      *
      * @return Context to use for offscreen rendering
      */
     static already_AddRefed<GLContext>
-    CreateOffscreen(const gfxIntSize& size,
-                    const SurfaceCaps& caps,
-                    ContextFlags flags = GLContext::ContextFlagsNone);
+    CreateOffscreen(const gfxIntSize& aSize,
+                    const ContextFormat& aFormat = ContextFormat::BasicRGBA32Format,
+                    const ContextFlags aFlags = GLContext::ContextFlagsNone);
 
     /**
      * Get a pointer to the global context, creating it if it doesn't exist.
      */
-    static GLContext*
-    GetGlobalContext(ContextFlags flags = GLContext::ContextFlagsNone);
+    static GLContext *
+    GetGlobalContext( const ContextFlags aFlags = GLContext::ContextFlagsNone);
 
     /**
      * Free any resources held by this Context Provider.
      */
     static void
     Shutdown();
 };
--- a/gfx/gl/GLContextProviderNull.cpp
+++ b/gfx/gl/GLContextProviderNull.cpp
@@ -11,24 +11,24 @@ namespace gl {
 already_AddRefed<GLContext>
 GLContextProviderNull::CreateForWindow(nsIWidget*)
 {
     return nullptr;
 }
 
 already_AddRefed<GLContext>
 GLContextProviderNull::CreateOffscreen(const gfxIntSize&,
-                                       const SurfaceCaps&,
-                                       ContextFlags)
+                                       const ContextFormat&,
+                                       const ContextFlags)
 {
     return nullptr;
 }
 
-GLContext*
-GLContextProviderNull::GetGlobalContext(ContextFlags)
+GLContext *
+GLContextProviderNull::GetGlobalContext()
 {
     return nullptr;
 }
 
 void
 GLContextProviderNull::Shutdown()
 {
 }
--- a/gfx/gl/GLContextProviderWGL.cpp
+++ b/gfx/gl/GLContextProviderWGL.cpp
@@ -15,18 +15,16 @@
 #include "gfxWindowsSurface.h"
 
 #include "gfxCrashReporterUtils.h"
 
 #include "prenv.h"
 
 #include "mozilla/Preferences.h"
 
-using namespace mozilla::gfx;
-
 namespace mozilla {
 namespace gl {
 
 typedef WGLLibrary::LibraryType LibType;
 
 WGLLibrary sWGLLib[WGLLibrary::LIBS_MAX];
 
 LibType
@@ -249,45 +247,42 @@ WGLLibrary::EnsureInitialized(bool aUseM
 
     reporter.SetSuccessful();
     return true;
 }
 
 class GLContextWGL : public GLContext
 {
 public:
-    // From Window: (possibly for offscreen!)
-    GLContextWGL(const SurfaceCaps& caps,
-                 GLContext* sharedContext,
-                 bool isOffscreen,
+    GLContextWGL(const ContextFormat& aFormat,
+                 GLContext *aSharedContext,
                  HDC aDC,
                  HGLRC aContext,
                  LibType aLibUsed,
-                 HWND aWindow = nullptr)
-        : GLContext(caps, sharedContext, isOffscreen),
+                 HWND aWindow = nullptr,
+                 bool aIsOffscreen = false)
+        : GLContext(aFormat, aIsOffscreen, aSharedContext),
           mDC(aDC),
           mContext(aContext),
           mWnd(aWindow),
           mPBuffer(NULL),
           mPixelFormat(0),
           mLibType(aLibUsed),
           mIsDoubleBuffered(false)
     {
     }
 
-    // From PBuffer
-    GLContextWGL(const SurfaceCaps& caps,
-                 GLContext* sharedContext,
-                 bool isOffscreen,
+    GLContextWGL(const ContextFormat& aFormat,
+                 GLContext *aSharedContext,
                  HANDLE aPbuffer,
                  HDC aDC,
                  HGLRC aContext,
                  int aPixelFormat,
                  LibType aLibUsed)
-        : GLContext(caps, sharedContext, isOffscreen),
+        : GLContext(aFormat, true, aSharedContext),
           mDC(aDC),
           mContext(aContext),
           mWnd(NULL),
           mPBuffer(aPbuffer),
           mPixelFormat(aPixelFormat),
           mLibType(aLibUsed),
           mIsDoubleBuffered(false)
     {
@@ -374,32 +369,91 @@ public:
         case NativeGLContext:
             return mContext;
 
         default:
             return nullptr;
         }
     }
 
+    bool BindTex2DOffscreen(GLContext *aOffscreen);
+    void UnbindTex2DOffscreen(GLContext *aOffscreen);
     bool ResizeOffscreen(const gfxIntSize& aNewSize);
 
     HGLRC Context() { return mContext; }
 
 protected:
     friend class GLContextProviderWGL;
 
     HDC mDC;
     HGLRC mContext;
     HWND mWnd;
     HANDLE mPBuffer;
     int mPixelFormat;
     LibType mLibType;
     bool mIsDoubleBuffered;
 };
 
+bool
+GLContextWGL::BindTex2DOffscreen(GLContext *aOffscreen)
+{
+    if (aOffscreen->GetContextType() != ContextTypeWGL) {
+        NS_WARNING("non-WGL context");
+        return false;
+    }
+
+    if (!aOffscreen->IsOffscreen()) {
+        NS_WARNING("non-offscreen context");
+        return false;
+    }
+
+    GLContextWGL *offs = static_cast<GLContextWGL*>(aOffscreen);
+
+    if (offs->mPBuffer) {
+        BOOL ok = sWGLLib[mLibType].fBindTexImage(offs->mPBuffer,
+                                            LOCAL_WGL_FRONT_LEFT_ARB);
+        if (!ok) {
+            NS_WARNING("CanvasLayerOGL::Updated wglBindTexImageARB failed");
+            return false;
+        }
+    } else if (offs->mOffscreenTexture) {
+          GLContext::ContextFlags flag = 
+                       sWGLLib[mLibType].GetLibraryType() == WGLLibrary::MESA_LLVMPIPE_LIB
+                       ? GLContext::ContextFlagsMesaLLVMPipe
+                       : GLContext::ContextFlagsNone;
+
+        if (offs->GetSharedContext() != GLContextProviderWGL::GetGlobalContext(flag))
+        {
+            NS_WARNING("offscreen FBO context can only be bound with context sharing!");
+            return false;
+        }
+
+        fBindTexture(LOCAL_GL_TEXTURE_2D, offs->mOffscreenTexture);
+    } else {
+        NS_WARNING("don't know how to bind this!");
+        return false;
+    }
+
+    return true;
+}
+
+void
+GLContextWGL::UnbindTex2DOffscreen(GLContext *aOffscreen)
+{
+    NS_ASSERTION(aOffscreen->GetContextType() == ContextTypeWGL, "wrong type");
+
+    GLContextWGL *offs = static_cast<GLContextWGL*>(aOffscreen);
+    if (offs->mPBuffer) {
+        // XXX so, according to the extension, ReleaseTexImage is not required to
+        // preserve color buffer contents.  This sucks, but everywhere that I've
+        // tried it the color buffer is preserved.  So let's cross our fingers..
+        sWGLLib[mLibType].fReleaseTexImage(offs->mPBuffer, LOCAL_WGL_FRONT_LEFT_ARB);
+    }
+}
+
 
 static bool
 GetMaxSize(HDC hDC, int format, gfxIntSize& size, LibType aLibToUse)
 {
     int query[] = {LOCAL_WGL_MAX_PBUFFER_WIDTH_ARB, LOCAL_WGL_MAX_PBUFFER_HEIGHT_ARB};
     int result[2];
 
     // (HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, int* piAttributes, int *piValues)
@@ -426,17 +480,53 @@ IsValidSizeForFormat(HDC hDC, int format
         return false;
 
     return true;
 }
 
 bool
 GLContextWGL::ResizeOffscreen(const gfxIntSize& aNewSize)
 {
-    return ResizeScreenBuffer(aNewSize);
+    if (mPBuffer) {
+        if (!IsValidSizeForFormat(sWGLLib[mLibType].GetWindowDC(), mPixelFormat, aNewSize, mLibType))
+            return false;
+
+        int pbattrs[] = {
+            LOCAL_WGL_TEXTURE_FORMAT_ARB,
+              mCreationFormat.alpha > 0 ? LOCAL_WGL_TEXTURE_RGBA_ARB
+                                        : LOCAL_WGL_TEXTURE_RGB_ARB,
+            LOCAL_WGL_TEXTURE_TARGET_ARB, LOCAL_WGL_TEXTURE_2D_ARB,
+            0
+        };
+
+        HANDLE newbuf = sWGLLib[mLibType].fCreatePbuffer(sWGLLib[mLibType].GetWindowDC(), mPixelFormat,
+                                                   aNewSize.width, aNewSize.height,
+                                                   pbattrs);
+        if (!newbuf)
+            return false;
+
+        if (sWGLLib[mLibType].fGetCurrentContext() == mContext) {
+            sWGLLib[mLibType].fMakeCurrent(NULL, NULL);
+        }
+
+        sWGLLib[mLibType].fDestroyPbuffer(mPBuffer);
+
+        mPBuffer = newbuf;
+        mDC = sWGLLib[mLibType].fGetPbufferDC(mPBuffer);
+
+        mOffscreenSize = aNewSize;
+        mOffscreenActualSize = aNewSize;
+
+        MakeCurrent();
+        ClearSafely();
+
+        return ResizeOffscreenFBOs(aNewSize, false);
+    }
+
+    return ResizeOffscreenFBOs(aNewSize, true);
 }
 
 static GLContextWGL *
 GetGlobalContextWGL(const GLContext::ContextFlags aFlags = GLContext::ContextFlagsNone)
 {
     return static_cast<GLContextWGL*>(GLContextProviderWGL::GetGlobalContext(aFlags));
 }
 
@@ -492,119 +582,132 @@ GLContextProviderWGL::CreateForWindow(ns
             shareContext = nullptr;
         }
     }
 
     if (!context) {
         return nullptr;
     }
 
-    SurfaceCaps caps = SurfaceCaps::ForRGBA();
-    nsRefPtr<GLContextWGL> glContext = new GLContextWGL(caps,
-                                                        shareContext,
-                                                        false,
-                                                        dc,
-                                                        context,
-                                                        libToUse);
+    nsRefPtr<GLContextWGL> glContext = new GLContextWGL(ContextFormat(ContextFormat::BasicRGB24),
+                                                        shareContext, dc, context, libToUse);
     if (!glContext->Init()) {
         return nullptr;
     }
 
     glContext->SetIsDoubleBuffered(sWGLLib[libToUse].UseDoubleBufferedWindows());
 
     return glContext.forget();
 }
 
 static already_AddRefed<GLContextWGL>
 CreatePBufferOffscreenContext(const gfxIntSize& aSize,
+                              const ContextFormat& aFormat,
                               LibType aLibToUse)
 {
-    WGLLibrary& wgl = sWGLLib[aLibToUse];
-
 #define A1(_a,_x)  do { _a.AppendElement(_x); } while(0)
 #define A2(_a,_x,_y)  do { _a.AppendElement(_x); _a.AppendElement(_y); } while(0)
 
     nsTArray<int> attrs;
 
     A2(attrs, LOCAL_WGL_SUPPORT_OPENGL_ARB, LOCAL_GL_TRUE);
     A2(attrs, LOCAL_WGL_DRAW_TO_PBUFFER_ARB, LOCAL_GL_TRUE);
     A2(attrs, LOCAL_WGL_DOUBLE_BUFFER_ARB, LOCAL_GL_FALSE);
 
     A2(attrs, LOCAL_WGL_ACCELERATION_ARB, LOCAL_WGL_FULL_ACCELERATION_ARB);
 
+    A2(attrs, LOCAL_WGL_COLOR_BITS_ARB, aFormat.colorBits());
+    A2(attrs, LOCAL_WGL_RED_BITS_ARB, aFormat.red);
+    A2(attrs, LOCAL_WGL_GREEN_BITS_ARB, aFormat.green);
+    A2(attrs, LOCAL_WGL_BLUE_BITS_ARB, aFormat.blue);
+    A2(attrs, LOCAL_WGL_ALPHA_BITS_ARB, aFormat.alpha);
+
+    A2(attrs, LOCAL_WGL_DEPTH_BITS_ARB, aFormat.depth);
+    A2(attrs, LOCAL_WGL_STENCIL_BITS_ARB, aFormat.stencil);
+
+    if (aFormat.alpha > 0) {
+        A2(attrs, LOCAL_WGL_BIND_TO_TEXTURE_RGBA_ARB, LOCAL_GL_TRUE);
+    } else {
+        A2(attrs, LOCAL_WGL_BIND_TO_TEXTURE_RGB_ARB, LOCAL_GL_TRUE);
+    }
+
     A2(attrs, LOCAL_WGL_DOUBLE_BUFFER_ARB, LOCAL_GL_FALSE);
     A2(attrs, LOCAL_WGL_STEREO_ARB, LOCAL_GL_FALSE);
 
     A1(attrs, 0);
 
     nsTArray<int> pbattrs;
+    A2(pbattrs, LOCAL_WGL_TEXTURE_TARGET_ARB, LOCAL_WGL_TEXTURE_2D_ARB);
+
+    if (aFormat.alpha > 0) {
+        A2(pbattrs, LOCAL_WGL_TEXTURE_FORMAT_ARB, LOCAL_WGL_TEXTURE_RGBA_ARB);
+    } else {
+        A2(pbattrs, LOCAL_WGL_TEXTURE_FORMAT_ARB, LOCAL_WGL_TEXTURE_RGB_ARB);
+    }
     A1(pbattrs, 0);
 
-#undef A1
-#undef A2
+    UINT numFormats = 256;
+    int formats[256];
 
-    // We only need one!
-    UINT numFormats = 1;
-    int formats[1];
-    HDC windowDC = wgl.GetWindowDC();
-    if (!wgl.fChoosePixelFormat(windowDC,
-                                attrs.Elements(), NULL,
-                                numFormats, formats, &numFormats)
+    if (!sWGLLib[aLibToUse].fChoosePixelFormat(sWGLLib[aLibToUse].GetWindowDC(),
+                                        attrs.Elements(), NULL,
+                                        numFormats, formats, &numFormats)
         || numFormats == 0)
     {
         return nullptr;
     }
 
-    // We don't care; just pick the first one.
+    // XXX add back the priority choosing code here
     int chosenFormat = formats[0];
-    if (!IsValidSizeForFormat(windowDC, chosenFormat, aSize, aLibToUse))
+
+    if (!IsValidSizeForFormat(sWGLLib[aLibToUse].GetWindowDC(), chosenFormat, aSize, aLibToUse))
         return nullptr;
 
-    HANDLE pbuffer = wgl.fCreatePbuffer(windowDC, chosenFormat,
-                                        aSize.width, aSize.height,
-                                        pbattrs.Elements());
+    HANDLE pbuffer = sWGLLib[aLibToUse].fCreatePbuffer(sWGLLib[aLibToUse].GetWindowDC(), chosenFormat,
+                                                aSize.width, aSize.height,
+                                                pbattrs.Elements());
     if (!pbuffer) {
         return nullptr;
     }
 
-    HDC pbdc = wgl.fGetPbufferDC(pbuffer);
+    HDC pbdc = sWGLLib[aLibToUse].fGetPbufferDC(pbuffer);
     NS_ASSERTION(pbdc, "expected a dc");
 
     HGLRC context;
-    if (wgl.HasRobustness()) {
+    if (sWGLLib[aLibToUse].HasRobustness()) {
         int attribs[] = {
             LOCAL_WGL_CONTEXT_FLAGS_ARB, LOCAL_WGL_CONTEXT_ROBUST_ACCESS_BIT_ARB,
             LOCAL_WGL_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB, LOCAL_WGL_LOSE_CONTEXT_ON_RESET_ARB,
             0
         };
 
-        context = wgl.fCreateContextAttribs(pbdc, nullptr, attribs);
+        context = sWGLLib[aLibToUse].fCreateContextAttribs(pbdc, nullptr, attribs);
     } else {
-        context = wgl.fCreateContext(pbdc);
+        context = sWGLLib[aLibToUse].fCreateContext(pbdc);
     }
 
     if (!context) {
-        wgl.fDestroyPbuffer(pbuffer);
+        sWGLLib[aLibToUse].fDestroyPbuffer(pbuffer);
         return nullptr;
     }
 
-	SurfaceCaps dummyCaps = SurfaceCaps::Any();
-    nsRefPtr<GLContextWGL> glContext = new GLContextWGL(dummyCaps,
-                                                        nullptr, true,
+    nsRefPtr<GLContextWGL> glContext = new GLContextWGL(aFormat,
+                                                        nullptr,
                                                         pbuffer,
                                                         pbdc,
                                                         context,
                                                         chosenFormat,
                                                         aLibToUse);
 
     return glContext.forget();
 }
 
 static already_AddRefed<GLContextWGL>
-CreateWindowOffscreenContext(GLContext::ContextFlags aFlags)
+CreateWindowOffscreenContext(const ContextFormat& aFormat,
+                             const GLContext::ContextFlags aFlags)
 {
     // CreateWindowOffscreenContext must return a global-shared context
     GLContextWGL *shareContext = GetGlobalContextWGL(aFlags);
     if (!shareContext) {
         return nullptr;
     }
     
     LibType libToUse = WGLLibrary::SelectLibrary(aFlags);
@@ -635,87 +738,89 @@ CreateWindowOffscreenContext(GLContext::
             return nullptr;
         }
     }
 
     if (!context) {
         return nullptr;
     }
 
-    SurfaceCaps caps = SurfaceCaps::ForRGBA();
-    nsRefPtr<GLContextWGL> glContext = new GLContextWGL(caps,
-                                                        shareContext, true,
-                                                        dc, context,
-                                                        libToUse, win);
+    nsRefPtr<GLContextWGL> glContext = new GLContextWGL(aFormat, shareContext,
+                                                        dc, context, libToUse,
+                                                        win, true);
 
     return glContext.forget();
 }
 
 already_AddRefed<GLContext>
-GLContextProviderWGL::CreateOffscreen(const gfxIntSize& size,
-                                      const SurfaceCaps& caps,
-                                      ContextFlags flags)
+GLContextProviderWGL::CreateOffscreen(const gfxIntSize& aSize,
+                                      const ContextFormat& aFormat,
+                                      const ContextFlags aFlags)
 {
-    LibType libToUse = WGLLibrary::SelectLibrary(flags);
+    LibType libToUse = WGLLibrary::SelectLibrary(aFlags);
     
     if (!sWGLLib[libToUse].EnsureInitialized(libToUse == WGLLibrary::MESA_LLVMPIPE_LIB)) {
         return nullptr;
     }
 
     nsRefPtr<GLContextWGL> glContext;
 
     // Always try to create a pbuffer context first, because we
     // want the context isolation.
-    if (sWGLLib[libToUse].fCreatePbuffer &&
+    NS_ENSURE_TRUE(Preferences::GetRootBranch(), nullptr);
+    const bool preferFBOs = Preferences::GetBool("wgl.prefer-fbo", false);
+    if (!preferFBOs &&
+        sWGLLib[libToUse].fCreatePbuffer &&
         sWGLLib[libToUse].fChoosePixelFormat)
     {
-        gfxIntSize dummySize = gfxIntSize(16, 16);
-        glContext = CreatePBufferOffscreenContext(dummySize, libToUse);
+        glContext = CreatePBufferOffscreenContext(aSize, aFormat,libToUse);
     }
 
     // If it failed, then create a window context and use a FBO.
     if (!glContext) {
-        glContext = CreateWindowOffscreenContext(flags);
+        glContext = CreateWindowOffscreenContext(aFormat, aFlags);
     }
 
     if (!glContext ||
         !glContext->Init())
     {
         return nullptr;
     }
 
-    if (!glContext->InitOffscreen(size, caps))
+    if (!glContext->ResizeOffscreenFBOs(aSize, !glContext->mPBuffer))
         return nullptr;
 
+    glContext->mOffscreenSize = aSize;
+    glContext->mOffscreenActualSize = aSize;
+
     return glContext.forget();
 }
 
 static nsRefPtr<GLContextWGL> gGlobalContext[WGLLibrary::LIBS_MAX];
 
 GLContext *
-GLContextProviderWGL::GetGlobalContext(const ContextFlags flags)
+GLContextProviderWGL::GetGlobalContext(const ContextFlags aFlags)
 {
-    LibType libToUse = WGLLibrary::SelectLibrary(flags);
+    LibType libToUse = WGLLibrary::SelectLibrary(aFlags);
     
     if (!sWGLLib[libToUse].EnsureInitialized(libToUse == WGLLibrary::MESA_LLVMPIPE_LIB)) {
         return nullptr;
     }
 
     static bool triedToCreateContext[WGLLibrary::LIBS_MAX] = {false, false};
 
     if (!triedToCreateContext[libToUse] && !gGlobalContext[libToUse]) {
         triedToCreateContext[libToUse] = true;
 
         // conveniently, we already have what we need...
-        SurfaceCaps dummyCaps = SurfaceCaps::Any();
-        gGlobalContext[libToUse] = new GLContextWGL(dummyCaps,
-                                                    nullptr, true,
-                                                    sWGLLib[libToUse].GetWindowDC(),
-                                                    sWGLLib[libToUse].GetWindowGLContext(),
-                                                    libToUse);
+        gGlobalContext[libToUse] = new GLContextWGL(ContextFormat(ContextFormat::BasicRGB24), 
+                                          nullptr,
+                                          sWGLLib[libToUse].GetWindowDC(), 
+                                          sWGLLib[libToUse].GetWindowGLContext(),
+                                          libToUse);
         if (!gGlobalContext[libToUse]->Init()) {
             NS_WARNING("Global context GLContext initialization failed?");
             gGlobalContext[libToUse] = nullptr;
             return nullptr;
         }
 
         gGlobalContext[libToUse]->SetIsGlobalSharedContext(true);
     }
--- a/gfx/gl/GLContextSymbols.h
+++ b/gfx/gl/GLContextSymbols.h
@@ -372,16 +372,14 @@ struct GLContextSymbols
     typedef void (GLAPIENTRY * PFNGLGETINTEGER64V) (GLenum pname, GLint64 *params);
     PFNGLGETINTEGER64V fGetInteger64v;
     typedef void (GLAPIENTRY * PFNGLGETSYNCIV) (GLsync sync, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *values);
     PFNGLGETSYNCIV fGetSynciv;
 
     // OES_egl_image
     typedef void (GLAPIENTRY * PFNGLEGLIMAGETARGETTEXTURE2D)(GLenum target, GLeglImage image);
     PFNGLEGLIMAGETARGETTEXTURE2D fEGLImageTargetTexture2D;
-    typedef void (GLAPIENTRY * PFNGLEGLIMAGETARGETRENDERBUFFERSTORAGE)(GLenum target, GLeglImage image);
-    PFNGLEGLIMAGETARGETRENDERBUFFERSTORAGE fEGLImageTargetRenderbufferStorage;
 };
 
 }
 }
 
 #endif /* GLCONTEXTSYMBOLS_H_ */
deleted file mode 100644
--- a/gfx/gl/GLContextTypes.cpp
+++ /dev/null
@@ -1,19 +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 "GLContextTypes.h"
-#include <cstring>
-
-using namespace mozilla::gl;
-
-GLFormats::GLFormats()
-{
-    std::memset(this, 0, sizeof(GLFormats));
-}
-
-PixelBufferFormat::PixelBufferFormat()
-{
-    std::memset(this, 0, sizeof(PixelBufferFormat));
-}
--- a/gfx/gl/GLContextTypes.h
+++ b/gfx/gl/GLContextTypes.h
@@ -1,16 +1,20 @@
 /* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
 /* 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 GLCONTEXT_TYPES_H_
-#define GLCONTEXT_TYPES_H_
+#ifndef GLCONTEXTSTUFF_H_
+#define GLCONTEXTSTUFF_H_
 
+/**
+ * We don't include GLDefs.h here since we don't want to drag in all defines
+ * in for all our users.
+ */
 typedef unsigned int GLenum;
 typedef unsigned int GLbitfield;
 typedef unsigned int GLuint;
 typedef int GLint;
 typedef int GLsizei;
 
 namespace mozilla {
 namespace gl {
@@ -27,44 +31,12 @@ enum ShaderProgramType {
     YCbCrLayerProgramType,
     ComponentAlphaPass1ProgramType,
     ComponentAlphaPass2ProgramType,
     Copy2DProgramType,
     Copy2DRectProgramType,
     NumProgramTypes
 };
 
-struct GLFormats
-{
-    // Constructs a zeroed object:
-    GLFormats();
-
-    GLenum color_texInternalFormat;
-    GLenum color_texFormat;
-    GLenum color_texType;
-    GLenum color_rbFormat;
-
-    GLenum depthStencil;
-    GLenum depth;
-    GLenum stencil;
-
-    GLsizei samples;
-};
-
+} // namespace gl
+} // namespace mozilla
 
-struct PixelBufferFormat
-{
-    // Constructs a zeroed object:
-    PixelBufferFormat();
-
-    int red, green, blue;
-    int alpha;
-    int depth, stencil;
-    int samples;
-
-    int ColorBits() const { return red + green + blue; }
-};
-
-
-} /* namespace gl */
-} /* namespace mozilla */
-
-#endif /* GLCONTEXT_TYPES_H_ */
+#endif /* GLCONTEXTSTUFF_H_ */
--- a/gfx/gl/GLContextUtils.cpp
+++ b/gfx/gl/GLContextUtils.cpp
@@ -22,22 +22,16 @@ varying vec2 vTexCoord;                 
 void main(void) {                           \n\
     vTexCoord = aPosition;                  \n\
     vec2 vertPos = aPosition * 2.0 - 1.0;   \n\
     gl_Position = vec4(vertPos, 0.0, 1.0);  \n\
 }                                           \n\
 ";
 
 static const char kTexBlit_FragShaderSource[] = "\
-#ifdef GL_FRAGMENT_PRECISION_HIGH                   \n\
-    precision highp float;                          \n\
-#else                                               \n\
-    precision mediump float;                        \n\
-#endif                                              \n\
-                                                    \n\
 uniform sampler2D uTexUnit;                         \n\
                                                     \n\
 varying vec2 vTexCoord;                             \n\
                                                     \n\
 void main(void) {                                   \n\
     gl_FragColor = texture2D(uTexUnit, vTexCoord);  \n\
 }                                                   \n\
 ";
@@ -221,75 +215,49 @@ GLContext::BlitFramebufferToFramebuffer(
                                         const gfxIntSize& destSize)
 {
     MOZ_ASSERT(!srcFB || fIsFramebuffer(srcFB));
     MOZ_ASSERT(!destFB || fIsFramebuffer(destFB));
 
     MOZ_ASSERT(IsExtensionSupported(EXT_framebuffer_blit) ||
                IsExtensionSupported(ANGLE_framebuffer_blit));
 
-    ScopedBindFramebuffer boundFB(this);
+    ScopedFramebufferBinding boundFB(this);
     ScopedGLState scissor(this, LOCAL_GL_SCISSOR_TEST, false);
 
-    BindReadFB(srcFB);
-    BindDrawFB(destFB);
+    BindUserReadFBO(srcFB);
+    BindUserDrawFBO(destFB);
 
     fBlitFramebuffer(0, 0,  srcSize.width,  srcSize.height,
                      0, 0, destSize.width, destSize.height,
                      LOCAL_GL_COLOR_BUFFER_BIT,
                      LOCAL_GL_NEAREST);
 }
 
 void
-GLContext::BlitFramebufferToFramebuffer(GLuint srcFB, GLuint destFB,
-                                        const gfxIntSize& srcSize,
-                                        const gfxIntSize& destSize,
-                                        const GLFormats& srcFormats)
-{
-    MOZ_ASSERT(!srcFB || fIsFramebuffer(srcFB));
-    MOZ_ASSERT(!destFB || fIsFramebuffer(destFB));
-
-    if (IsExtensionSupported(EXT_framebuffer_blit) ||
-        IsExtensionSupported(ANGLE_framebuffer_blit))
-    {
-        BlitFramebufferToFramebuffer(srcFB, destFB,
-                                     srcSize, destSize);
-        return;
-    }
-
-    GLuint tex = CreateTextureForOffscreen(srcFormats, srcSize);
-    MOZ_ASSERT(tex);
-
-    BlitFramebufferToTexture(srcFB, tex, srcSize, srcSize);
-    BlitTextureToFramebuffer(tex, destFB, srcSize, destSize);
-
-    fDeleteTextures(1, &tex);
-}
-
-void
 GLContext::BlitTextureToFramebuffer(GLuint srcTex, GLuint destFB,
                                     const gfxIntSize& srcSize,
                                     const gfxIntSize& destSize)
 {
     MOZ_ASSERT(fIsTexture(srcTex));
     MOZ_ASSERT(!destFB || fIsFramebuffer(destFB));
 
     if (IsExtensionSupported(EXT_framebuffer_blit) ||
         IsExtensionSupported(ANGLE_framebuffer_blit))
     {
-        ScopedFramebufferForTexture srcWrapper(this, srcTex);
+        ScopedFramebufferTexture srcWrapper(this, srcTex);
         MOZ_ASSERT(srcWrapper.IsComplete());
 
         BlitFramebufferToFramebuffer(srcWrapper.FB(), destFB,
                                      srcSize, destSize);
         return;
     }
 
 
-    ScopedBindFramebuffer boundFB(this, destFB);
+    ScopedFramebufferBinding boundFB(this, destFB);
 
     GLuint boundTexUnit = 0;
     GetUIntegerv(LOCAL_GL_ACTIVE_TEXTURE, &boundTexUnit);
     fActiveTexture(LOCAL_GL_TEXTURE0);
 
     GLuint boundTex = 0;
     GetUIntegerv(LOCAL_GL_TEXTURE_BINDING_2D, &boundTex);
     fBindTexture(LOCAL_GL_TEXTURE_2D, srcTex);
@@ -397,52 +365,60 @@ GLContext::BlitFramebufferToTexture(GLui
                                     const gfxIntSize& destSize)
 {
     MOZ_ASSERT(!srcFB || fIsFramebuffer(srcFB));
     MOZ_ASSERT(fIsTexture(destTex));
 
     if (IsExtensionSupported(EXT_framebuffer_blit) ||
         IsExtensionSupported(ANGLE_framebuffer_blit))
     {
-        ScopedFramebufferForTexture destWrapper(this, destTex);
+        ScopedFramebufferTexture destWrapper(this, destTex);
+        MOZ_ASSERT(destWrapper.IsComplete());
 
         BlitFramebufferToFramebuffer(srcFB, destWrapper.FB(),
                                      srcSize, destSize);
         return;
     }
 
-    ScopedBindTexture autoTex(this, destTex);
-    ScopedBindFramebuffer boundFB(this, srcFB);
+    GLuint boundTex = 0;
+    GetUIntegerv(LOCAL_GL_TEXTURE_BINDING_2D, &boundTex);
+    fBindTexture(LOCAL_GL_TEXTURE_2D, destTex);
+
+    ScopedFramebufferBinding boundFB(this, srcFB);
     ScopedGLState scissor(this, LOCAL_GL_SCISSOR_TEST, false);
 
     fCopyTexSubImage2D(LOCAL_GL_TEXTURE_2D, 0,
                        0, 0,
                        0, 0,
                        srcSize.width, srcSize.height);
+
+    fBindTexture(LOCAL_GL_TEXTURE_2D, boundTex);
 }
 
 void
 GLContext::BlitTextureToTexture(GLuint srcTex, GLuint destTex,
                                 const gfxIntSize& srcSize,
                                 const gfxIntSize& destSize)
 {
     MOZ_ASSERT(fIsTexture(srcTex));
     MOZ_ASSERT(fIsTexture(destTex));
 
     if (mTexBlit_UseDrawNotCopy) {
         // Draw is texture->framebuffer
-        ScopedFramebufferForTexture destWrapper(this, destTex);
+        ScopedFramebufferTexture destWrapper(this, destTex);
+        MOZ_ASSERT(destWrapper.IsComplete());
 
         BlitTextureToFramebuffer(srcTex, destWrapper.FB(),
                                  srcSize, destSize);
         return;
     }
 
     // Generally, just use the CopyTexSubImage path
-    ScopedFramebufferForTexture srcWrapper(this, srcTex);
+    ScopedFramebufferTexture srcWrapper(this, srcTex);
+    MOZ_ASSERT(srcWrapper.IsComplete());
 
     BlitFramebufferToTexture(srcWrapper.FB(), destTex,
                              srcSize, destSize);
 }
 
 uint32_t GetBitsPerTexel(GLenum format, GLenum type)
 {
     // If there is no defined format or type, we're not taking up any memory
--- a/gfx/gl/GLDefs.h
+++ b/gfx/gl/GLDefs.h
@@ -42,37 +42,16 @@ typedef ptrdiff_t GLintptr;
 // ARB_sync
 typedef struct __GLsync* GLsync;
 typedef int64_t GLint64;
 typedef uint64_t GLuint64;
 
 // OES_EGL_image (GLES)
 typedef void* GLeglImage;
 
-// EGL types
-typedef int EGLint;
-typedef unsigned int EGLBoolean;
-typedef unsigned int EGLenum;
-typedef void *EGLConfig;
-typedef void *EGLContext;
-typedef void *EGLDisplay;
-typedef void *EGLSurface;
-typedef void *EGLClientBuffer;
-typedef void *EGLCastToRelevantPtr;
-typedef void *EGLImage;
-typedef void *EGLSync;
-typedef uint64_t EGLTime;
-
-#define EGL_NO_CONTEXT       ((EGLContext)0)
-#define EGL_NO_DISPLAY       ((EGLDisplay)0)
-#define EGL_NO_SURFACE       ((EGLSurface)0)
-#define EGL_NO_CONFIG        ((EGLConfig)nullptr)
-#define EGL_NO_SYNC          ((EGLSync)0)
-#define EGL_NO_IMAGE         ((EGLImage)0)
-
 #ifndef GLAPIENTRY
 # ifdef WIN32
 #  define GLAPIENTRY APIENTRY
 #  define GLAPI
 # else
 #  define GLAPIENTRY
 #  define GLAPI
 # endif
@@ -3291,19 +3270,16 @@ typedef uint64_t EGLTime;
 #define LOCAL_EGL_IMAGE_PRESERVED             0x30D2
 
 // EGL_KHR_image_pixmap
 #define LOCAL_EGL_NATIVE_PIXMAP               0x30B0
 
 // EGL_KHR_gl_texture_2D_image
 #define LOCAL_EGL_GL_TEXTURE_2D               0x30B1
 
-// EGL_KHR_gl_renderbuffer_image
-#define LOCAL_EGL_GL_RENDERBUFFER             0x30B9
-
 // OES_EGL_image_external
 #define LOCAL_GL_TEXTURE_EXTERNAL             0x8D65
 
 // EGL_KHR_fence_sync
 #define LOCAL_EGL_SYNC_FENCE                  0x30F9
 #define LOCAL_EGL_SYNC_TYPE                   0x30F7
 #define LOCAL_EGL_SYNC_STATUS                 0x30F1
 #define LOCAL_EGL_SYNC_CONDITION              0x30F8
@@ -3311,15 +3287,9 @@ typedef uint64_t EGLTime;
 #define LOCAL_EGL_UNSIGNALED                  0x30F3
 #define LOCAL_EGL_SYNC_PRIOR_COMMANDS_COMPLETE  0x30F0
 #define LOCAL_EGL_SYNC_FLUSH_COMMANDS_BIT     0x0001
 #define LOCAL_EGL_FOREVER                     0xFFFFFFFFFFFFFFFFull
 #define LOCAL_EGL_TIMEOUT_EXPIRED             0x30F5
 #define LOCAL_EGL_CONDITION_SATISFIED         0x30F6
 #define LOCAL_EGL_SUCCESS                     0x3000
 
-// EGL_ANGLE_surface_d3d_texture_2d_share_handle
-#define LOCAL_EGL_D3D_TEXTURE_2D_SHARE_HANDLE_ANGLE 0x3200
-
-// FAKE_EGL_image_android
-#define LOCAL_EGL_NATIVE_BUFFER_ANDROID       0x3140
-
 #endif
--- a/gfx/gl/GLLibraryEGL.cpp
+++ b/gfx/gl/GLLibraryEGL.cpp
@@ -5,17 +5,16 @@
 #include "GLLibraryEGL.h"
 
 #include "gfxCrashReporterUtils.h"
 #include "mozilla/Preferences.h"
 #include "nsDirectoryServiceDefs.h"
 #include "nsDirectoryServiceUtils.h"
 #include "nsPrintfCString.h"
 #include "prenv.h"
-#include "GLContext.h"
 
 namespace mozilla {
 namespace gl {
 
 // should match the order of EGLExtensions, and be null-terminated.
 static const char *sExtensionNames[] = {
     "EGL_KHR_image_base",
     "EGL_KHR_image_pixmap",
@@ -252,40 +251,16 @@ GLLibraryEGL::EnsureInitialized()
 
             mSymbols.fCreateSync = nullptr;
             mSymbols.fDestroySync = nullptr;
             mSymbols.fClientWaitSync = nullptr;
             mSymbols.fGetSyncAttrib = nullptr;
         }
     }
 
-    if (IsExtensionSupported(KHR_image) || IsExtensionSupported(KHR_image_base)) {
-        GLLibraryLoader::SymLoadStruct imageSymbols[] = {
-            { (PRFuncPtr*) &mSymbols.fCreateImage,  { "eglCreateImageKHR",  nullptr } },
-            { (PRFuncPtr*) &mSymbols.fDestroyImage, { "eglDestroyImageKHR", nullptr } },
-            { nullptr, { nullptr } }
-        };
-
-        bool success = GLLibraryLoader::LoadSymbols(mEGLLibrary,
-                                                    &imageSymbols[0],
-                                                    lookupFunction);
-        if (!success) {
-            NS_ERROR("EGL supports KHR_image(_base) without exposing its functions!");
-
-            MarkExtensionUnsupported(KHR_image);
-            MarkExtensionUnsupported(KHR_image_base);
-            MarkExtensionUnsupported(KHR_image_pixmap);
-
-            mSymbols.fCreateImage = nullptr;
-            mSymbols.fDestroyImage = nullptr;
-        }
-    } else {
-        MarkExtensionUnsupported(KHR_image_pixmap);
-    }
-
     mInitialized = true;
     reporter.SetSuccessful();
     return true;
 }
 
 void
 GLLibraryEGL::InitExtensions()
 {
@@ -310,16 +285,47 @@ GLLibraryEGL::InitExtensions()
     mAvailableExtensions.Load(extensions, sExtensionNames, firstRun && debugMode);
 
 #ifdef DEBUG
     firstRun = false;
 #endif
 }
 
 void
+GLLibraryEGL::LoadConfigSensitiveSymbols()
+{
+    GLLibraryLoader::PlatformLookupFunction lookupFunction =
+            (GLLibraryLoader::PlatformLookupFunction)mSymbols.fGetProcAddress;
+
+    if (IsExtensionSupported(KHR_image) || IsExtensionSupported(KHR_image_base)) {
+        GLLibraryLoader::SymLoadStruct imageSymbols[] = {
+            { (PRFuncPtr*) &mSymbols.fCreateImage,  { "eglCreateImageKHR",  nullptr } },
+            { (PRFuncPtr*) &mSymbols.fDestroyImage, { "eglDestroyImageKHR", nullptr } },
+            { nullptr, { nullptr } }
+        };
+
+        bool success = GLLibraryLoader::LoadSymbols(mEGLLibrary,
+                                                    &imageSymbols[0],
+                                                    lookupFunction);
+        if (!success) {
+            NS_ERROR("EGL supports KHR_image(_base) without exposing its functions!");
+
+            MarkExtensionUnsupported(KHR_image);
+            MarkExtensionUnsupported(KHR_image_base);
+            MarkExtensionUnsupported(KHR_image_pixmap);
+
+            mSymbols.fCreateImage = nullptr;
+            mSymbols.fDestroyImage = nullptr;
+        }
+    } else {
+        MarkExtensionUnsupported(KHR_image_pixmap);
+    }
+}
+
+void
 GLLibraryEGL::DumpEGLConfig(EGLConfig cfg)
 {
     int attrval;
     int err;
 
 #define ATTR(_x) do {                                                   \
         fGetConfigAttrib(mEGLDisplay, cfg, LOCAL_EGL_##_x, &attrval);  \
         if ((err = fGetError()) != 0x3000) {                        \
--- a/gfx/gl/GLLibraryEGL.h
+++ b/gfx/gl/GLLibraryEGL.h
@@ -9,16 +9,28 @@
 #include "mozilla/X11Util.h"
 #endif
 
 #include "GLContext.h"
 #include "GLLibraryLoader.h"
 
 #include "nsIFile.h"
 
+typedef int EGLint;
+typedef unsigned int EGLBoolean;
+typedef unsigned int EGLenum;
+typedef void *EGLConfig;
+typedef void *EGLContext;
+typedef void *EGLDisplay;
+typedef void *EGLSurface;
+typedef void *EGLClientBuffer;
+typedef void *EGLCastToRelevantPtr;
+typedef void *EGLImage;
+typedef void *EGLSync;
+typedef uint64_t EGLTime;
 
 #if defined(XP_WIN)
 
 #ifndef WIN32_LEAN_AND_MEAN
 #define WIN32_LEAN_AND_MEAN 1
 #endif
 
 #include <windows.h>
@@ -39,28 +51,30 @@ typedef void *EGLNativeWindowType;
 // on android as we can use LD_PRELOAD or other tricks
 // on other platforms. We look for it in /data/local
 // as that's writeable by all users
 //
 // This should really go in GLLibraryEGL.cpp but we currently reference
 // APITRACE_LIB in GLContextProviderEGL.cpp. Further refactoring
 // will come in subsequent patches on Bug 732865
 #define APITRACE_LIB "/data/local/egltrace.so"
-
-#ifdef MOZ_WIDGET_ANDROID
-
-#endif // MOZ_WIDGET_ANDROID
 #endif // ANDROID
 #endif
 
 #if defined(MOZ_X11)
 #define EGL_DEFAULT_DISPLAY  ((EGLNativeDisplayType)mozilla::DefaultXDisplay())
 #else
 #define EGL_DEFAULT_DISPLAY  ((EGLNativeDisplayType)0)
 #endif
+#define EGL_NO_CONTEXT       ((EGLContext)0)
+#define EGL_NO_DISPLAY       ((EGLDisplay)0)
+#define EGL_NO_SURFACE       ((EGLSurface)0)
+#define EGL_NO_SYNC          ((EGLSync)0)
+
+#define EGL_DISPLAY()        sEGLLibrary.Display()
 
 namespace mozilla {
 namespace gl {
 
 #ifdef DEBUG
 #undef BEFORE_GL_CALL
 #undef AFTER_GL_CALL
 
@@ -436,16 +450,17 @@ public:
         return IsExtensionSupported(ANGLE_surface_d3d_texture_2d_share_handle);
     }
 
     bool HasRobustness() {
         return IsExtensionSupported(EXT_create_context_robustness);
     }
 
     bool EnsureInitialized();
+    void LoadConfigSensitiveSymbols();
 
     void DumpEGLConfig(EGLConfig cfg);
     void DumpEGLConfigs();
 
     struct {
         typedef EGLDisplay (GLAPIENTRY * pfnGetDisplay)(void *display_id);
         pfnGetDisplay fGetDisplay;
         typedef EGLSurface (GLAPIENTRY * pfnGetCurrentSurface)(EGLint);
deleted file mode 100644
--- a/gfx/gl/GLScreenBuffer.cpp
+++ /dev/null
@@ -1,619 +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 "GLScreenBuffer.h"
-
-#include <cstring>
-#include "gfxImageSurface.h"
-#include "GLContext.h"
-#include "SharedSurfaceGL.h"
-#include "SurfaceStream.h"
-
-using namespace mozilla::gfx;
-
-namespace mozilla {
-namespace gl {
-
-GLScreenBuffer*
-GLScreenBuffer::Create(GLContext* gl,
-                     const gfxIntSize& size,
-                     const SurfaceCaps& caps)
-{
-    if (caps.antialias &&
-        !gl->SupportsFramebufferMultisample())
-    {
-        return nullptr;
-    }
-
-    SurfaceFactory_GL* factory = new SurfaceFactory_Basic(gl, caps);
-    SurfaceStream* stream = SurfaceStream::CreateForType(
-        SurfaceStream::ChooseGLStreamType(SurfaceStream::MainThread,
-                                          caps.preserve),
-        nullptr);
-
-    return new GLScreenBuffer(gl, caps, factory, stream);
-}
-
-GLScreenBuffer::~GLScreenBuffer()
-{
-    delete mFactory;
-    delete mStream;
-    delete mDraw;
-    delete mRead;
-}
-
-
-void
-GLScreenBuffer::BindAsFramebuffer(GLContext* const gl, GLenum target) const
-{
-    GLuint drawFB = DrawFB();
-    GLuint readFB = ReadFB();
-
-    if (!gl->HasExt_FramebufferBlit()) {
-        MOZ_ASSERT(drawFB == readFB);
-        gl->raw_fBindFramebuffer(target, readFB);
-        return;
-    }
-
-    switch (target) {
-    case LOCAL_GL_FRAMEBUFFER:
-        gl->raw_fBindFramebuffer(LOCAL_GL_DRAW_FRAMEBUFFER_EXT, drawFB);
-        gl->raw_fBindFramebuffer(LOCAL_GL_READ_FRAMEBUFFER_EXT, readFB);
-        break;
-
-    case LOCAL_GL_DRAW_FRAMEBUFFER_EXT:
-        if (!gl->HasExt_FramebufferBlit())
-            NS_WARNING("DRAW_FRAMEBUFFER requested but unavailable.");
-
-        gl->raw_fBindFramebuffer(LOCAL_GL_DRAW_FRAMEBUFFER_EXT, drawFB);
-        break;
-
-    case LOCAL_GL_READ_FRAMEBUFFER_EXT:
-        if (!gl->HasExt_FramebufferBlit())
-            NS_WARNING("READ_FRAMEBUFFER requested but unavailable.");
-
-        gl->raw_fBindFramebuffer(LOCAL_GL_READ_FRAMEBUFFER_EXT, readFB);
-        break;
-
-    default:
-        // In case we got a bad target.
-        MOZ_NOT_REACHED("Bad `target` for BindFramebuffer.");
-        gl->raw_fBindFramebuffer(target, 0);
-        break;
-    }
-}
-
-void
-GLScreenBuffer::BindFB(GLuint fb)
-{
-    GLuint drawFB = DrawFB();
-    GLuint readFB = ReadFB();
-
-    mUserDrawFB = fb;
-    mUserReadFB = fb;
-    mInternalDrawFB = (fb == 0) ? drawFB : fb;
-    mInternalReadFB = (fb == 0) ? readFB : fb;
-
-    if (mInternalDrawFB == mInternalReadFB) {
-        mGL->raw_fBindFramebuffer(LOCAL_GL_FRAMEBUFFER, mInternalDrawFB);
-    } else {
-        MOZ_ASSERT(mGL->SupportsSplitFramebuffer());
-        mGL->raw_fBindFramebuffer(LOCAL_GL_DRAW_FRAMEBUFFER_EXT, mInternalDrawFB);
-        mGL->raw_fBindFramebuffer(LOCAL_GL_READ_FRAMEBUFFER_EXT, mInternalReadFB);
-    }
-
-#ifdef DEBUG
-    mInInternalMode_DrawFB = false;
-    mInInternalMode_ReadFB = false;
-#endif
-}
-
-void
-GLScreenBuffer::BindDrawFB(GLuint fb)
-{
-    if (!mGL->SupportsSplitFramebuffer()) {
-        NS_WARNING("DRAW_FRAMEBUFFER requested, but unsupported.");
-
-        mGL->raw_fBindFramebuffer(LOCAL_GL_DRAW_FRAMEBUFFER_EXT, fb);
-    } else {
-        GLuint drawFB = DrawFB();
-        mUserDrawFB = fb;
-        mInternalDrawFB = (fb == 0) ? drawFB : fb;
-
-        mGL->raw_fBindFramebuffer(LOCAL_GL_DRAW_FRAMEBUFFER_EXT, mInternalDrawFB);
-    }
-
-#ifdef DEBUG
-    mInInternalMode_DrawFB = false;
-#endif
-}
-
-void
-GLScreenBuffer::BindReadFB(GLuint fb)
-{
-    if (!mGL->SupportsSplitFramebuffer()) {
-        NS_WARNING("READ_FRAMEBUFFER requested, but unsupported.");
-
-        mGL->raw_fBindFramebuffer(LOCAL_GL_READ_FRAMEBUFFER_EXT, fb);
-    } else {
-        GLuint readFB = ReadFB();
-        mUserReadFB = fb;
-        mInternalReadFB = (fb == 0) ? readFB : fb;
-
-        mGL->raw_fBindFramebuffer(LOCAL_GL_READ_FRAMEBUFFER_EXT, mInternalReadFB);
-    }
-
-#ifdef DEBUG
-    mInInternalMode_ReadFB = false;
-#endif
-}
-
-void
-GLScreenBuffer::BindDrawFB_Internal(GLuint fb)
-{
-  mInternalDrawFB = mUserDrawFB = fb;
-  mGL->raw_fBindFramebuffer(LOCAL_GL_DRAW_FRAMEBUFFER_EXT, mInternalDrawFB);
-
-#ifdef DEBUG
-    mInInternalMode_DrawFB = true;
-#endif
-}
-
-void
-GLScreenBuffer::BindReadFB_Internal(GLuint fb)
-{
-  mInternalReadFB = mUserReadFB = fb;
-  mGL->raw_fBindFramebuffer(LOCAL_GL_READ_FRAMEBUFFER_EXT, mInternalReadFB);
-
-#ifdef DEBUG
-    mInInternalMode_ReadFB = true;
-#endif
-}
-
-
-GLuint
-GLScreenBuffer::GetDrawFB() const
-{
-#ifdef DEBUG
-    MOZ_ASSERT(mGL->IsCurrent());
-    MOZ_ASSERT(!mInInternalMode_DrawFB);
-
-    // Don't need a branch here, because:
-    // LOCAL_GL_DRAW_FRAMEBUFFER_BINDING_EXT == LOCAL_GL_FRAMEBUFFER_BINDING == 0x8CA6
-    // We use raw_ here because this is debug code and we need to see what
-    // the driver thinks.
-    GLuint actual = 0;
-    mGL->raw_fGetIntegerv(LOCAL_GL_DRAW_FRAMEBUFFER_BINDING_EXT, (GLint*)&actual);
-
-    GLuint predicted = mInternalDrawFB;
-    if (predicted != actual) {
-        printf_stderr("Misprediction: Bound draw FB predicted: %d. Was: %d.\n",
-                      predicted, actual);
-        MOZ_ASSERT(false, "Draw FB binding misprediction!");
-    }
-#endif
-
-    return mUserDrawFB;
-}
-
-GLuint
-GLScreenBuffer::GetReadFB() const
-{
-#ifdef DEBUG
-    MOZ_ASSERT(mGL->IsCurrent());
-    MOZ_ASSERT(!mInInternalMode_ReadFB);
-
-    // We use raw_ here because this is debug code and we need to see what
-    // the driver thinks.
-    GLuint actual = 0;
-    if (mGL->SupportsSplitFramebuffer())
-        mGL->raw_fGetIntegerv(LOCAL_GL_READ_FRAMEBUFFER_BINDING_EXT, (GLint*)&actual);
-    else
-        mGL->raw_fGetIntegerv(LOCAL_GL_FRAMEBUFFER_BINDING, (GLint*)&actual);
-
-    GLuint predicted = mInternalReadFB;
-    if (predicted != actual) {
-        printf_stderr("Misprediction: Bound read FB predicted: %d. Was: %d.\n",
-                      predicted, actual);
-        MOZ_ASSERT(false, "Read FB binding misprediction!");
-    }
-#endif
-
-    return mUserReadFB;
-}
-
-GLuint
-GLScreenBuffer::GetFB() const
-{
-    MOZ_ASSERT(GetDrawFB() == GetReadFB());
-    return GetDrawFB();
-}
-
-
-void
-GLScreenBuffer::DeletingFB(GLuint fb)
-{
-    if (fb == mInternalDrawFB) {
-        mInternalDrawFB = 0;
-        mUserDrawFB = 0;
-    }
-    if (fb == mInternalReadFB) {
-        mInternalReadFB = 0;
-        mUserReadFB = 0;
-    }
-}
-
-
-void
-GLScreenBuffer::AfterDrawCall()
-{
-    if (mUserDrawFB != 0)
-        return;
-
-    RequireBlit();
-}
-
-void
-GLScreenBuffer::BeforeReadCall()
-{
-    if (mUserReadFB != 0)
-        return;
-
-    AssureBlitted();
-}
-
-void
-GLScreenBuffer::RequireBlit()
-{
-    mNeedsBlit = true;
-}
-
-void
-GLScreenBuffer::AssureBlitted()
-{
-    if (!mNeedsBlit)
-        return;
-
-    if (mDraw) {
-        GLuint drawFB = DrawFB();
-        GLuint readFB = ReadFB();
-
-        MOZ_ASSERT(drawFB != 0);
-        MOZ_ASSERT(drawFB != readFB);
-        MOZ_ASSERT(mGL->IsExtensionSupported(GLContext::EXT_framebuffer_blit) ||
-                   mGL->IsExtensionSupported(GLContext::ANGLE_framebuffer_blit));
-        MOZ_ASSERT(mDraw->Size() == mRead->Size());
-
-        ScopedBindFramebuffer boundFB(mGL);
-        ScopedGLState scissor(mGL, LOCAL_GL_SCISSOR_TEST, false);
-
-        BindReadFB_Internal(drawFB);
-        BindDrawFB_Internal(readFB);
-
-        const gfxIntSize&  srcSize = mDraw->Size();
-        const gfxIntSize& destSize = mRead->Size();
-
-        mGL->raw_fBlitFramebuffer(0, 0,  srcSize.width,  srcSize.height,
-                                  0, 0, destSize.width, destSize.height,
-                                  LOCAL_GL_COLOR_BUFFER_BIT,
-                                  LOCAL_GL_NEAREST);
-        // Done!
-    }
-
-    mNeedsBlit = false;
-}
-
-void
-GLScreenBuffer::Morph(SurfaceFactory_GL* newFactory, SurfaceStreamType streamType)
-{
-    MOZ_ASSERT(mStream);
-
-    if (newFactory) {
-        delete mFactory;
-        mFactory = newFactory;
-    }
-
-    if (mStream->mType == streamType)
-        return;
-
-    SurfaceStream* newStream = SurfaceStream::CreateForType(streamType, mStream);
-    MOZ_ASSERT(newStream);
-
-    delete mStream;
-    mStream = newStream;
-}
-
-bool
-GLScreenBuffer::Swap(const gfxIntSize& size)
-{
-    ScopedBindFramebuffer autoFB(mGL);
-
-    SharedSurface* nextSurf = mStream->SwapProducer(mFactory, size);
-    if (!nextSurf) {
-        SurfaceFactory_GL* basicFactory =
-            new SurfaceFactory_Basic(mGL, mFactory->Caps());
-        nextSurf = mStream->SwapProducer(basicFactory, size);
-        if (!nextSurf) {
-            delete basicFactory;
-            return false;
-        }
-
-        // Swap out the apparently defective old factory.
-        delete mFactory;
-        mFactory = basicFactory;
-    }
-
-    SharedSurface_GL* surf = SharedSurface_GL::Cast(nextSurf);
-    if (mRead && SharedSurf())
-        SharedSurf()->UnlockProd();
-
-    surf->LockProd();
-
-    if (mRead &&
-        surf->AttachType() == SharedSurf()->AttachType() &&
-        size == Size())
-    {
-        // Same size, same type, ready for reuse!
-        mRead->Attach(surf);
-    } else {
-        // Else something changed, so resize:
-        DrawBuffer* draw = CreateDraw(size);  // Can be null.
-        ReadBuffer* read = CreateRead(surf);
-        MOZ_ASSERT(read); // Should never fail if SwapProd succeeded.
-
-        delete mDraw;
-        delete mRead;
-
-        mDraw = draw;
-        mRead = read;
-    }
-
-    // Check that we're all set up.
-    MOZ_ASSERT(SharedSurf() == surf);
-
-    if (!PreserveBuffer()) {
-        // DiscardFramebuffer here could help perf on some mobile platforms.
-    }
-
-    return true;
-}
-
-bool
-GLScreenBuffer::PublishFrame(const gfxIntSize& size)
-{
-    AssureBlitted();
-
-    bool good = Swap(size);
-    return good;
-}
-
-
-DrawBuffer*
-GLScreenBuffer::CreateDraw(const gfxIntSize& size)
-{
-    GLContext* gl = mFactory->GL();
-    const GLFormats& formats = mFactory->Formats();
-    const SurfaceCaps& caps = mFactory->DrawCaps();
-
-    return DrawBuffer::Create(gl, caps, formats, size);
-}
-
-ReadBuffer*
-GLScreenBuffer::CreateRead(SharedSurface_GL* surf)
-{
-    GLContext* gl = mFactory->GL();
-    const GLFormats& formats = mFactory->Formats();
-    const SurfaceCaps& caps = mFactory->ReadCaps();
-
-    return ReadBuffer::Create(gl, caps, formats, surf);
-}
-
-
-void
-GLScreenBuffer::Readback(SharedSurface_GL* src, gfxImageSurface* dest)
-{
-    MOZ_ASSERT(src && dest);
-    MOZ_ASSERT(dest->GetSize() == src->Size());
-    MOZ_ASSERT(dest->Format() == (src->HasAlpha() ? gfxImageSurface::ImageFormatARGB32
-                                                  : gfxImageSurface::ImageFormatRGB24));
-
-    mGL->MakeCurrent();
-
-    bool needsSwap = src != SharedSurf();
-    if (needsSwap) {
-        SharedSurf()->UnlockProd();
-        src->LockProd();
-    }
-
-    ReadBuffer* buffer = CreateRead(src);
-    MOZ_ASSERT(buffer);
-
-    ScopedBindFramebuffer autoFB(mGL, buffer->FB());
-    mGL->ReadPixelsIntoImageSurface(dest);
-
-    delete buffer;
-
-    if (needsSwap) {
-        src->UnlockProd();
-        SharedSurf()->LockProd();
-    }
-}
-
-
-
-DrawBuffer*
-DrawBuffer::Create(GLContext* const gl,
-                   const SurfaceCaps& caps,
-                   const GLFormats& formats,
-                   const gfxIntSize& size)
-{
-    if (!caps.color) {
-        MOZ_ASSERT(!caps.alpha && !caps.depth && !caps.stencil);
-
-        // Nothing is needed.
-        return nullptr;
-    }
-
-    GLuint colorMSRB = 0;
-    GLuint depthRB   = 0;
-    GLuint stencilRB = 0;
-
-    GLuint* pColorMSRB = caps.antialias ? &colorMSRB : nullptr;
-    GLuint* pDepthRB   = caps.depth     ? &depthRB   : nullptr;
-    GLuint* pStencilRB = caps.stencil   ? &stencilRB : nullptr;
-
-    if (!formats.color_rbFormat)
-        pColorMSRB = nullptr;
-
-    if (pDepthRB && pStencilRB) {
-        if (!formats.depth && !formats.depthStencil)
-            pDepthRB = nullptr;
-
-        if (!formats.stencil && !formats.depthStencil)
-            pStencilRB = nullptr;
-    } else {
-        if (!formats.depth)
-            pDepthRB = nullptr;
-
-        if (!formats.stencil)
-            pStencilRB = nullptr;
-    }
-
-    gl->CreateRenderbuffersForOffscreen(formats, size, caps.antialias,
-                                        pColorMSRB, pDepthRB, pStencilRB);
-
-    GLuint fb = 0;
-    gl->fGenFramebuffers(1, &fb);
-    gl->AttachBuffersToFB(0, colorMSRB, depthRB, stencilRB, fb);
-    MOZ_ASSERT(gl->IsFramebufferComplete(fb));
-
-    return new DrawBuffer(gl, size, fb, colorMSRB, depthRB, stencilRB);
-}
-
-DrawBuffer::~DrawBuffer()
-{
-    mGL->MakeCurrent();
-
-    GLuint fb = mFB;
-    GLuint rbs[] = {
-        mColorMSRB,
-        mDepthRB,
-        mStencilRB
-    };
-
-    mGL->fDeleteFramebuffers(1, &fb);
-    mGL->fDeleteRenderbuffers(3, rbs);
-}
-
-
-
-
-
-
-ReadBuffer*
-ReadBuffer::Create(GLContext* gl,
-                   const SurfaceCaps& caps,
-                   const GLFormats& formats,
-                   SharedSurface_GL* surf)
-{
-    MOZ_ASSERT(surf);
-
-    if (surf->AttachType() == AttachmentType::Screen) {
-        // Don't need anything. Our read buffer will be the 'screen'.
-
-        return new ReadBuffer(gl,
-                              0, 0, 0,
-                              surf);
-    }
-
-    GLuint depthRB = 0;
-    GLuint stencilRB = 0;
-
-    GLuint* pDepthRB   = caps.depth   ? &depthRB   : nullptr;
-    GLuint* pStencilRB = caps.stencil ? &stencilRB : nullptr;
-
-    gl->CreateRenderbuffersForOffscreen(formats, surf->Size(), caps.antialias,
-                                        nullptr, pDepthRB, pStencilRB);
-
-    GLuint colorTex = 0;
-    GLuint colorRB = 0;
-
-    switch (surf->AttachType()) {
-    case AttachmentType::GLTexture:
-        colorTex = surf->Texture();
-        break;
-    case AttachmentType::GLRenderbuffer:
-        colorRB = surf->Renderbuffer();
-        break;
-    default:
-        MOZ_NOT_REACHED("Unknown attachment type?");
-        return nullptr;
-    }
-    MOZ_ASSERT(colorTex || colorRB);
-
-    GLuint fb = 0;
-    gl->fGenFramebuffers(1, &fb);
-    gl->AttachBuffersToFB(colorTex, colorRB, depthRB, stencilRB, fb);
-
-    MOZ_ASSERT(gl->IsFramebufferComplete(fb));
-
-    return new ReadBuffer(gl,
-                          fb, depthRB, stencilRB,
-                          surf);
-}
-
-ReadBuffer::~ReadBuffer()
-{
-    mGL->MakeCurrent();
-
-    GLuint fb = mFB;
-    GLuint rbs[] = {
-        mDepthRB,
-        mStencilRB
-    };
-
-    mGL->fDeleteFramebuffers(1, &fb);
-    mGL->fDeleteRenderbuffers(2, rbs);
-}
-
-void
-ReadBuffer::Attach(SharedSurface_GL* surf)
-{
-    MOZ_ASSERT(surf && mSurf);
-    MOZ_ASSERT(surf->AttachType() == mSurf->AttachType());
-    MOZ_ASSERT(surf->Size() == mSurf->Size());
-
-    // Nothing else is needed for AttachType Screen.
-    if (surf->AttachType() != AttachmentType::Screen) {
-        GLuint colorTex = 0;
-        GLuint colorRB = 0;
-
-        switch (surf->AttachType()) {
-        case AttachmentType::GLTexture:
-            colorTex = surf->Texture();
-            break;
-        case AttachmentType::GLRenderbuffer:
-            colorRB = surf->Renderbuffer();
-            break;
-        default:
-            MOZ_NOT_REACHED("Unknown attachment type?");
-            return;
-        }
-
-        mGL->AttachBuffersToFB(colorTex, colorRB, 0, 0, mFB);
-        MOZ_ASSERT(mGL->IsFramebufferComplete(mFB));
-    }
-
-    mSurf = surf;
-}
-
-const gfxIntSize&
-ReadBuffer::Size() const
-{
-    return mSurf->Size();
-}
-
-} /* namespace gl */
-} /* namespace mozilla */
deleted file mode 100644
--- a/gfx/gl/GLScreenBuffer.h
+++ /dev/null
@@ -1,296 +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/. */
-
-/* GLScreenBuffer is the abstraction for the "default framebuffer" used
- * by an offscreen GLContext. Since it's only for offscreen GLContext's,
- * it's only useful for things like WebGL, and is NOT used by the
- * compositor's GLContext. Remember that GLContext provides an abstraction
- * so that even if you want to draw to the 'screen', even if that's not
- * 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 "GLContextTypes.h"
-#include "GLDefs.h"
-#include "gfxPoint.h"
-
-// Forwards:
-class gfxImageSurface;
-
-namespace mozilla {
-    namespace gfx {
-        class SurfaceStream;
-        class SharedSurface;
-    }
-    namespace gl {
-        class GLContext;
-        class SharedSurface_GL;
-        class SurfaceFactory_GL;
-    }
-}
-
-namespace mozilla {
-namespace gl {
-
-class DrawBuffer
-{
-protected:
-    typedef struct gfx::SurfaceCaps SurfaceCaps;
-
-public:
-    // Infallible, may return null if unneeded.
-    static DrawBuffer* Create(GLContext* const gl,
-                              const SurfaceCaps& caps,
-                              const GLFormats& formats,
-                              const gfxIntSize& size);
-
-protected:
-    GLContext* const mGL;
-    const gfxIntSize mSize;
-    const GLuint mFB;
-    const GLuint mColorMSRB;
-    const GLuint mDepthRB;
-    const GLuint mStencilRB;
-
-    DrawBuffer(GLContext* gl,
-               const gfxIntSize& size,
-               GLuint fb,
-               GLuint colorMSRB,
-               GLuint depthRB,
-               GLuint stencilRB)
-        : mGL(gl)
-        , mSize(size)
-        , mFB(fb)
-        , mColorMSRB(colorMSRB)
-        , mDepthRB(depthRB)
-        , mStencilRB(stencilRB)
-    {}
-
-public:
-    virtual ~DrawBuffer();
-
-    const gfxIntSize& Size() const {
-        return mSize;
-    }
-
-    GLuint FB() const {
-        return mFB;
-    }
-};
-
-class ReadBuffer
-{
-protected:
-    typedef struct gfx::SurfaceCaps SurfaceCaps;
-
-public:
-    // Infallible, always non-null.
-    static ReadBuffer* Create(GLContext* gl,
-                              const SurfaceCaps& caps,
-                              const GLFormats& formats,
-                              SharedSurface_GL* surf);
-
-protected:
-    GLContext* const mGL;
-
-    const GLuint mFB;
-    // mFB has the following attachments:
-    const GLuint mDepthRB;
-    const GLuint mStencilRB;
-    // note no mColorRB here: this is provided by mSurf.
-    SharedSurface_GL* mSurf; // Owned by GLScreenBuffer's SurfaceStream.
-
-    ReadBuffer(GLContext* gl,
-               GLuint fb,
-               GLuint depthRB,
-               GLuint stencilRB,
-               SharedSurface_GL* surf)
-        : mGL(gl)
-        , mFB(fb)
-        , mDepthRB(depthRB)
-        , mStencilRB(stencilRB)
-        , mSurf(surf)
-    {}
-
-public:
-    virtual ~ReadBuffer();
-
-    // Cannot attach a surf of a different AttachType or Size than before.
-    void Attach(SharedSurface_GL* surf);
-
-    const gfxIntSize& Size() const;
-
-    GLuint FB() const {
-        return mFB;
-    }
-
-    SharedSurface_GL* SharedSurf() const {
-        return mSurf;
-    }
-};
-
-
-class GLScreenBuffer
-{
-protected:
-    typedef class gfx::SurfaceStream SurfaceStream;
-    typedef class gfx::SharedSurface SharedSurface;
-    typedef gfx::SurfaceStreamType SurfaceStreamType;
-    typedef gfx::SharedSurfaceType SharedSurfaceType;
-    typedef struct gfx::SurfaceCaps SurfaceCaps;
-
-public:
-    // Infallible.
-    static GLScreenBuffer* Create(GLContext* gl,
-                                  const gfxIntSize& size,
-                                  const SurfaceCaps& caps);
-
-protected:
-    GLContext* const mGL;         // Owns us.
-    SurfaceCaps mCaps;
-    SurfaceFactory_GL* mFactory;  // Owned by us.
-    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;
-    GLuint mUserReadFB;
-    GLuint mInternalDrawFB;
-    GLuint mInternalReadFB;
-
-#ifdef DEBUG
-    bool mInInternalMode_DrawFB;
-    bool mInInternalMode_ReadFB;
-#endif
-
-    GLScreenBuffer(GLContext* gl,
-                   const SurfaceCaps& caps,
-                   SurfaceFactory_GL* factory,
-                   SurfaceStream* stream)
-        : mGL(gl)
-        , mCaps(caps)
-        , mFactory(factory)
-        , mStream(stream)
-        , mDraw(nullptr)
-        , mRead(nullptr)
-        , mNeedsBlit(true)
-        , mUserDrawFB(0)
-        , mUserReadFB(0)
-        , mInternalDrawFB(0)
-        , mInternalReadFB(0)
-#ifdef DEBUG
-        , mInInternalMode_DrawFB(true)
-        , mInInternalMode_ReadFB(true)
-#endif
-    {}
-
-public:
-    virtual ~GLScreenBuffer();
-
-    SurfaceStream* Stream() const {
-        return mStream;
-    }
-
-    SurfaceFactory_GL* Factory() const {
-        return mFactory;
-    }
-
-    SharedSurface_GL* SharedSurf() const {
-        MOZ_ASSERT(mRead);
-        return mRead->SharedSurf();
-    }
-
-    bool PreserveBuffer() const {
-        return mCaps.preserve;
-    }
-
-    const SurfaceCaps& Caps() const {
-        return mCaps;
-    }
-
-    GLuint DrawFB() const {
-        if (!mDraw)
-            return ReadFB();
-
-        return mDraw->FB();
-    }
-
-    GLuint ReadFB() const {
-        return mRead->FB();
-    }
-
-    void DeletingFB(GLuint fb);
-
-    const gfxIntSize& Size() const {
-        MOZ_ASSERT(mRead);
-        MOZ_ASSERT(!mDraw || mDraw->Size() == mRead->Size());
-        return mRead->Size();
-    }
-
-    void BindAsFramebuffer(GLContext* const gl, GLenum target) const;
-
-    void RequireBlit();
-    void AssureBlitted();
-    void AfterDrawCall();
-    void BeforeReadCall();
-
-    /* Morph swaps out our SurfaceStream mechanism and replaces it with
-     * one best suited to our platform and compositor configuration.
-     *
-     * Must be called on the producing thread.
-     * We haven't made any guarantee that rendering is actually
-     * done when Morph is run, just that it can't run concurrently
-     * with rendering. This means that we can't just drop the contents
-     * of the buffer, since we may only be partially done rendering.
-     *
-     * Once you pass newFactory into Morph, newFactory will be owned by
-     * GLScreenBuffer, so `forget` any references to it that still exist.
-     */
-    void Morph(SurfaceFactory_GL* newFactory, SurfaceStreamType streamType);
-
-protected:
-    // Returns false on error or inability to resize.
-    bool Swap(const gfxIntSize& size);
-
-public:
-    bool PublishFrame(const gfxIntSize& size);
-
-    void Readback(SharedSurface_GL* src, gfxImageSurface* dest);
-
-protected:
-    DrawBuffer* CreateDraw(const gfxIntSize& size);
-    ReadBuffer* CreateRead(SharedSurface_GL* surf);
-
-public:
-    /* `fb` in these functions is the framebuffer the GLContext is hoping to
-     * bind. When this is 0, we intercept the call and bind our own
-     * framebuffers. As a client of these functions, just bind 0 when you want
-     * to draw to the default framebuffer/'screen'.
-     */
-    void BindFB(GLuint fb);
-    void BindDrawFB(GLuint fb);
-    void BindReadFB(GLuint fb);
-    GLuint GetFB() const;
-    GLuint GetDrawFB() const;
-    GLuint GetReadFB() const;
-
-    // Here `fb` is the actual framebuffer you want bound. Binding 0 will
-    // bind the (generally useless) default framebuffer.
-    void BindDrawFB_Internal(GLuint fb);
-    void BindReadFB_Internal(GLuint fb);
-};
-
-}   // namespace gl
-}   // namespace mozilla
-
-#endif  // SCREEN_BUFFER_H_
--- a/gfx/gl/GLXLibrary.h
+++ b/gfx/gl/GLXLibrary.h
@@ -82,17 +82,17 @@ public:
     void xWaitX();
 
     GLXContext xCreateContextAttribs(Display* display, 
                                      GLXFBConfig config, 
                                      GLXContext share_list, 
                                      Bool direct,
                                      const int* attrib_list);
 
-    bool EnsureInitialized(LibraryType libType);
+    bool EnsureInitialized(bool aUseMesaLLVMPipe);
 
     GLXPixmap CreatePixmap(gfxASurface* aSurface);
     void DestroyPixmap(GLXPixmap aPixmap);
     void BindTexImage(GLXPixmap aPixmap);
     void ReleaseTexImage(GLXPixmap aPixmap);
 
     bool UseTextureFromPixmap() { return mUseTextureFromPixmap; }
     bool HasRobustness() { return mHasRobustness; }
--- a/gfx/gl/Makefile.in
+++ b/gfx/gl/Makefile.in
@@ -1,75 +1,60 @@
 # 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/.
 
-DEPTH     = @DEPTH@
-topsrcdir = @top_srcdir@
-srcdir    = @srcdir@
-VPATH     = @srcdir@
+DEPTH		= @DEPTH@
+topsrcdir	= @top_srcdir@
+srcdir		= @srcdir@
+VPATH		= @srcdir@
 
 include $(DEPTH)/config/autoconf.mk
 
-MODULE           = gl
-LIBRARY_NAME     = gl
-LIBXUL_LIBRARY   = 1
-EXPORT_LIBRARY   = 1
+MODULE		= gl
+LIBRARY_NAME	= gl
+LIBXUL_LIBRARY	= 1
+EXPORT_LIBRARY	= 1
 FAIL_ON_WARNINGS = 1
 
 EXPORTS	= \
-  ForceDiscreteGPUHelperCGL.h \
-  GLContext.h \
-  GLContextProvider.h \
-  GLContextProviderImpl.h \
-  GLContextSymbols.h \
-  GLContextTypes.h \
-  GLDefs.h \
-  GLLibraryLoader.h \
-  GLLibraryEGL.h \
-  GLScreenBuffer.h \
-  GLTextureImage.h \
-  SharedSurface.h \
-  SharedSurfaceEGL.h \
-  SharedSurfaceGL.h \
-  SurfaceFactory.h \
-  SurfaceStream.h \
-  SurfaceTypes.h \
-  $(NULL)
+	GLDefs.h \
+	GLContext.h \
+	GLContextTypes.h \
+	GLContextSymbols.h \
+	GLContextProvider.h \
+	GLContextProviderImpl.h \
+	GLLibraryLoader.h \
+	ForceDiscreteGPUHelperCGL.h \
+	GLTextureImage.h \
+	$(NULL)
 
 ifdef MOZ_X11
 EXPORTS += \
-  GLXLibrary.h \
-  $(NULL)
+	GLXLibrary.h \
+	$(NULL)
 endif
 
 
 ifeq ($(MOZ_WIDGET_TOOLKIT),windows)
 EXPORTS	+= \
-  WGLLibrary.h \
-  $(NULL)
+	WGLLibrary.h \
+	$(NULL)
 ifdef MOZ_WEBGL
 DEFINES += -DMOZ_WEBGL
 DEFINES += -DMOZ_D3DCOMPILER_DLL=$(MOZ_D3DCOMPILER_DLL)
 endif
 endif
 
 CPPSRCS	= \
-  GLContext.cpp \
-  GLContextTypes.cpp \
-  GLContextUtils.cpp \
-  GLLibraryLoader.cpp \
-  GLScreenBuffer.cpp \
-  GLTextureImage.cpp \
-  SharedSurface.cpp \
-  SharedSurfaceEGL.cpp \
-  SharedSurfaceGL.cpp \
-  SurfaceFactory.cpp \
-  SurfaceStream.cpp \
-  $(NULL)
+	GLContext.cpp \
+	GLContextUtils.cpp \
+	GLLibraryLoader.cpp \
+	GLTextureImage.cpp \
+	$(NULL)
 
 GL_PROVIDER = Null
 
 ifeq ($(MOZ_WIDGET_TOOLKIT),windows)
 GL_PROVIDER = WGL
 endif
 
 ifeq ($(MOZ_WIDGET_TOOLKIT),cocoa)
@@ -117,29 +102,23 @@ CPPSRCS += GLContextProvider$(GL_PROVIDE
 endif
 
 ifeq ($(GL_PROVIDER),EGL)
 CPPSRCS += GLLibraryEGL.cpp
 endif
 
 # Win32 is a special snowflake, for ANGLE
 ifeq ($(MOZ_WIDGET_TOOLKIT),windows)
-EXPORTS += \
-  SharedSurfaceANGLE.h \
-  $(NULL)
-
 CPPSRCS += \
-  GLContextProviderEGL.cpp \
-  GLLibraryEGL.cpp \
-  SharedSurfaceANGLE.cpp \
-  $(NULL)
+	GLContextProviderEGL.cpp \
+	GLLibraryEGL.cpp
 endif
 
 ifdef MOZ_ANDROID_OMTC
 DEFINES += -DMOZ_ANDROID_OMTC
 endif
 
 include $(topsrcdir)/config/rules.mk
 
 DEFINES := $(filter-out -DUNICODE,$(DEFINES))
 
 CXXFLAGS += $(MOZ_CAIRO_CFLAGS) $(MOZ_PIXMAN_CFLAGS) $(TK_CFLAGS)
-CFLAGS   += $(MOZ_CAIRO_CFLAGS) $(MOZ_PIXMAN_CFLAGS) $(TK_CFLAGS)
+CFLAGS += $(MOZ_CAIRO_CFLAGS) $(MOZ_PIXMAN_CFLAGS) $(TK_CFLAGS)
deleted file mode 100644
--- a/gfx/gl/SharedSurface.cpp
+++ /dev/null
@@ -1,29 +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 "SharedSurface.h"
-#include "SharedSurfaceGL.h"
-
-using namespace mozilla::gl;
-
-namespace mozilla {
-namespace gfx {
-
-// |src| must begin and end locked, though it
-// can be temporarily unlocked if needed.
-void
-SharedSurface::Copy(SharedSurface* src, SharedSurface* dest, SurfaceFactory* factory)
-{
-    MOZ_ASSERT( src->APIType() == APITypeT::OpenGL);
-    MOZ_ASSERT(dest->APIType() == APITypeT::OpenGL);
-
-    SharedSurface_GL* srcGL = (SharedSurface_GL*)src;
-    SharedSurface_GL* destGL = (SharedSurface_GL*)dest;
-
-    SharedSurface_GL::Copy(srcGL, destGL, (SurfaceFactory_GL*)factory);
-}
-
-} /* namespace gfx */
-} /* namespace mozilla */
deleted file mode 100644
--- a/gfx/gl/SharedSurface.h
+++ /dev/null
@@ -1,122 +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/. */
-
-/* SharedSurface abstracts an actual surface (can be a GL texture, but
- * not necessarily) that handles sharing.
- * Its specializations are:
- *     SharedSurface_Basic (client-side bitmap, does readback)
- *     SharedSurface_GLTexture
- *     SharedSurface_EGLImage
- *     SharedSurface_ANGLEShareHandle
- */
-
-#ifndef SHARED_SURFACE_H_
-#define SHARED_SURFACE_H_
-
-#include "mozilla/StandardInteger.h"
-#include "mozilla/Attributes.h"
-#include "GLDefs.h"
-#include "gfxPoint.h"
-#include "SurfaceTypes.h"
-
-namespace mozilla {
-namespace gfx {
-
-class SurfaceFactory;
-
-class SharedSurface
-{
-protected:
-    const SharedSurfaceType mType;
-    const APITypeT mAPI;
-    const AttachmentType mAttachType;
-    const gfxIntSize mSize;
-    const bool mHasAlpha;
-    bool mIsLocked;
-
-    SharedSurface(SharedSurfaceType type,
-                  APITypeT api,
-                  AttachmentType attachType,
-                  const gfxIntSize& size,
-                  bool hasAlpha)
-        : mType(type)
-        , mAPI(api)
-        , mAttachType(attachType)
-        , mSize(size)
-        , mHasAlpha(hasAlpha)
-        , mIsLocked(false)
-    {
-    }
-
-public:
-    virtual ~SharedSurface() {
-    }
-
-    static void Copy(SharedSurface* src, SharedSurface* dest,
-                     SurfaceFactory* factory);
-
-    // This locks the SharedSurface as the production buffer for the context.
-    // This is needed by backends which use PBuffers and/or EGLSurfaces.
-    virtual void LockProd() {
-        MOZ_ASSERT(!mIsLocked);
-        LockProdImpl();
-        mIsLocked = true;
-    }
-
-    // Unlocking is harmless if we're already unlocked.
-    virtual void UnlockProd() {
-        if (!mIsLocked)
-            return;
-
-        UnlockProdImpl();
-        mIsLocked = false;
-    }
-
-    virtual void LockProdImpl() = 0;
-    virtual void UnlockProdImpl() = 0;
-
-    virtual void Fence() = 0;
-    virtual bool WaitSync() = 0;
-
-
-    SharedSurfaceType Type() const {
-        return mType;
-    }
-
-    APITypeT APIType() const {
-        return mAPI;
-    }
-
-    AttachmentType AttachType() const {
-        return mAttachType;
-    }
-
-    const gfxIntSize& Size() const {
-        return mSize;
-    }
-
-    bool HasAlpha() const {
-        return mHasAlpha;
-    }
-
-
-    // For use when AttachType is correct.
-    virtual GLuint Texture() const {
-        MOZ_ASSERT(AttachType() == AttachmentType::GLTexture);
-        MOZ_NOT_REACHED("Did you forget to override this function?");
-        return 0;
-    }
-
-    virtual GLuint Renderbuffer() const {
-        MOZ_ASSERT(AttachType() == AttachmentType::GLRenderbuffer);
-        MOZ_NOT_REACHED("Did you forget to override this function?");
-        return 0;
-    }
-};
-
-} /* namespace gfx */
-} /* namespace mozilla */
-
-#endif /* SHARED_SURFACE_H_ */
deleted file mode 100644
--- a/gfx/gl/SharedSurfaceANGLE.cpp
+++ /dev/null
@@ -1,275 +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 "SharedSurfaceANGLE.h"
-
-#include "GLContext.h"
-
-using namespace mozilla::gfx;
-
-namespace mozilla {
-namespace gl {
-
-SurfaceFactory_ANGLEShareHandle*
-SurfaceFactory_ANGLEShareHandle::Create(GLContext* gl,
-                                        ID3D10Device1* d3d,
-                                        const SurfaceCaps& caps)
-{
-    GLLibraryEGL* egl = gl->GetLibraryEGL();
-    if (!egl)
-        return nullptr;
-
-    if (!egl->IsExtensionSupported(
-            GLLibraryEGL::ANGLE_surface_d3d_texture_2d_share_handle))
-    {
-        return nullptr;
-    }
-
-    return new SurfaceFactory_ANGLEShareHandle(gl, egl, d3d, caps);
-}
-
-EGLDisplay
-SharedSurface_ANGLEShareHandle::Display()
-{
-    return mEGL->Display();
-}
-
-
-SharedSurface_ANGLEShareHandle::~SharedSurface_ANGLEShareHandle()
-{
-    mEGL->fDestroySurface(Display(), mPBuffer);
-}
-
-void
-SharedSurface_ANGLEShareHandle::LockProdImpl()
-{
-    mGL->MakeCurrent_EGLSurface(mPBuffer);
-}
-
-void
-SharedSurface_ANGLEShareHandle::UnlockProdImpl()
-{
-}
-
-
-void
-SharedSurface_ANGLEShareHandle::Fence()
-{
-    mGL->fFinish();
-}
-
-bool
-SharedSurface_ANGLEShareHandle::WaitSync()
-{
-    // Since we glFinish in Fence(), we're always going to be resolved here.
-    return true;
-}
-
-static void
-FillPBufferAttribs_ByBits(nsTArray<EGLint>& aAttrs,
-                          int redBits, int greenBits,
-                          int blueBits, int alphaBits,
-                          int depthBits, int stencilBits)
-{
-    aAttrs.Clear();
-
-#if defined(A1) || defined(A2)
-#error The temp-macro names we want are already defined.
-#endif
-
-#define A1(_x)      do { aAttrs.AppendElement(_x); } while (0)
-#define A2(_x,_y)   do { A1(_x); A1(_y); } while (0)
-
-    A2(LOCAL_EGL_RENDERABLE_TYPE, LOCAL_EGL_OPENGL_ES2_BIT);
-    A2(LOCAL_EGL_SURFACE_TYPE, LOCAL_EGL_PBUFFER_BIT);
-
-    A2(LOCAL_EGL_RED_SIZE, redBits);
-    A2(LOCAL_EGL_GREEN_SIZE, greenBits);
-    A2(LOCAL_EGL_BLUE_SIZE, blueBits);
-    A2(LOCAL_EGL_ALPHA_SIZE, alphaBits);
-
-    A2(LOCAL_EGL_DEPTH_SIZE, depthBits);
-    A2(LOCAL_EGL_STENCIL_SIZE, stencilBits);
-
-    A1(LOCAL_EGL_NONE);
-#undef A1
-#undef A2
-}
-
-static void
-FillPBufferAttribs_BySizes(nsTArray<EGLint>& attribs,
-                           bool bpp16, bool hasAlpha,
-                           int depthBits, int stencilBits)
-{
-    int red = 0;
-    int green = 0;
-    int blue = 0;
-    int alpha = 0;
-
-    if (bpp16) {
-        if (hasAlpha) {
-            red = green = blue = alpha = 4;
-        } else {
-            red = 5;
-            green = 6;
-            blue = 5;
-        }
-    } else {
-        red = green = blue = 8;
-        if (hasAlpha)
-            alpha = 8;
-    }
-
-    FillPBufferAttribs_ByBits(attribs,
-                              red, green, blue, alpha,
-                              depthBits, stencilBits);
-}
-
-static EGLConfig
-ChooseConfig(GLContext* gl,
-             GLLibraryEGL* egl,
-             const SurfaceCaps& caps)
-{
-    MOZ_ASSERT(egl);
-    MOZ_ASSERT(caps.color);
-
-    // We might want 24-bit depth, but we're only (fairly) sure to get 16-bit.
-    int depthBits = caps.depth ? 16 : 0;
-    int stencilBits = caps.stencil ? 8 : 0;
-
-    // Ok, now we have everything.
-    nsTArray<EGLint> attribs(32);
-    FillPBufferAttribs_BySizes(attribs,
-                               caps.bpp16, caps.alpha,
-                               depthBits, stencilBits);
-
-    // Time to try to get this config:
-    EGLConfig configs[64];
-    int numConfigs = sizeof(configs)/sizeof(EGLConfig);
-    int foundConfigs = 0;
-
-    if (!egl->fChooseConfig(egl->Display(),
-                            attribs.Elements(),
-                            configs, numConfigs,
-                            &foundConfigs) ||
-        !foundConfigs)
-    {
-        NS_WARNING("No configs found for the requested formats.");
-        return EGL_NO_CONFIG;
-    }
-
-    // TODO: Pick a config progamatically instead of hoping that
-    // the first config will be minimally matching our request.
-    EGLConfig config = configs[0];
-
-    if (gl->DebugMode()) {
-        egl->DumpEGLConfig(config);
-    }
-
-    return config;
-}
-
-
-// Returns EGL_NO_SURFACE on error.
-static EGLSurface CreatePBufferSurface(GLLibraryEGL* egl,
-                                       EGLDisplay display,
-                                       EGLConfig config,
-                                       const gfxIntSize& size)
-{
-    EGLint attribs[] = {
-        LOCAL_EGL_WIDTH, size.width,
-        LOCAL_EGL_HEIGHT, size.height,
-        LOCAL_EGL_NONE
-    };
-
-    EGLSurface surface = egl->fCreatePbufferSurface(display, config, attribs);
-
-    return surface;
-}
-
-SharedSurface_ANGLEShareHandle*
-SharedSurface_ANGLEShareHandle::Create(GLContext* gl, ID3D10Device1* d3d,
-                                       EGLContext context, EGLConfig config,
-                                       const gfxIntSize& size, bool hasAlpha)
-{
-    GLLibraryEGL* egl = gl->GetLibraryEGL();
-    MOZ_ASSERT(egl);
-    MOZ_ASSERT(egl->IsExtensionSupported(
-               GLLibraryEGL::ANGLE_surface_d3d_texture_2d_share_handle));
-
-    if (!context || !config)
-        return nullptr;
-
-    EGLDisplay display = egl->Display();
-    EGLSurface pbuffer = CreatePBufferSurface(egl, display, config, size);
-    if (!pbuffer)
-        return nullptr;
-
-
-    // Declare everything before 'goto's.
-    HANDLE shareHandle = nullptr;
-    nsRefPtr<ID3D10Texture2D> texture;
-    nsRefPtr<ID3D10ShaderResourceView> srv;
-
-    // On failure, goto CleanUpIfFailed.
-    // If |failed|, CleanUpIfFailed will clean up and return null.
-    bool failed = true;
-
-    // Off to the races!
-    if (!egl->fQuerySurfacePointerANGLE(
-            display,
-            pbuffer,
-            LOCAL_EGL_D3D_TEXTURE_2D_SHARE_HANDLE_ANGLE,
-            &shareHandle))
-    {
-        NS_ERROR("Failed to grab ShareHandle for PBuffer!");
-        goto CleanUpIfFailed;
-    }
-
-    // Ok, we have a valid PBuffer with ShareHandle.
-    // Let's attach it to D3D.
-    HRESULT hr = d3d->OpenSharedResource(shareHandle,
-                                         __uuidof(ID3D10Texture2D),
-                                         getter_AddRefs(texture));
-    if (FAILED(hr))
-        goto CleanUpIfFailed;
-
-    hr = d3d->CreateShaderResourceView(texture, nullptr, getter_AddRefs(srv));
-    if (FAILED(hr))
-        goto CleanUpIfFailed;
-
-    failed = false;
-
-CleanUpIfFailed:
-    if (failed) {
-        NS_WARNING("CleanUpIfFailed");
-        egl->fDestroySurface(egl->Display(), pbuffer);
-        MOZ_CRASH();
-        return nullptr;
-    }
-
-    return new SharedSurface_ANGLEShareHandle(gl, egl,
-                                              size, hasAlpha,
-                                              context, pbuffer,
-                                              texture, srv);
-}
-
-
-SurfaceFactory_ANGLEShareHandle::SurfaceFactory_ANGLEShareHandle(GLContext* gl,
-                                                                 GLLibraryEGL* egl,
-                                                                 ID3D10Device1* d3d,
-                                                                 const SurfaceCaps& caps)
-    : SurfaceFactory_GL(gl, SharedSurfaceType::EGLSurfaceANGLE, caps)
-    , mProdGL(gl)
-    , mEGL(egl)
-    , mConsD3D(d3d)
-{
-    mConfig = ChooseConfig(mProdGL, mEGL, mReadCaps);
-    mContext = mProdGL->GetEGLContext();
-    MOZ_ASSERT(mConfig && mContext);
-}
-
-} /* namespace gl */
-} /* namespace mozilla */
deleted file mode 100644
--- a/gfx/gl/SharedSurfaceANGLE.h
+++ /dev/null
@@ -1,115 +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/. */
-
-#ifndef SHARED_SURFACE_ANGLE_H_
-#define SHARED_SURFACE_ANGLE_H_
-
-#include "SharedSurfaceGL.h"
-#include "SurfaceFactory.h"
-#include "GLLibraryEGL.h"
-#include "SurfaceTypes.h"
-
-#include <windows.h>
-#include <d3d10_1.h>
-
-namespace mozilla {
-namespace gl {
-
-class GLContext;
-
-class SharedSurface_ANGLEShareHandle
-    : public SharedSurface_GL
-{
-public:
-    static SharedSurface_ANGLEShareHandle* Create(GLContext* gl, ID3D10Device1* d3d,
-                                                  EGLContext context, EGLConfig config,
-                                                  const gfxIntSize& size,
-                                                  bool hasAlpha);
-
-    static SharedSurface_ANGLEShareHandle* Cast(SharedSurface* surf) {
-        MOZ_ASSERT(surf->Type() == SharedSurfaceType::EGLSurfaceANGLE);
-
-        return (SharedSurface_ANGLEShareHandle*)surf;
-    }
-
-protected:
-    GLLibraryEGL* const mEGL;
-    const EGLContext mContext;
-    const EGLSurface mPBuffer;
-    nsRefPtr<ID3D10Texture2D> mTexture;
-    nsRefPtr<ID3D10ShaderResourceView> mSRV;
-
-    SharedSurface_ANGLEShareHandle(GLContext* gl,
-                                   GLLibraryEGL* egl,
-                                   const gfxIntSize& size,
-                                   bool hasAlpha,
-                                   EGLContext context,
-                                   EGLSurface pbuffer,
-                                   ID3D10Texture2D* texture,
-                                   ID3D10ShaderResourceView* srv)
-        : SharedSurface_GL(SharedSurfaceType::EGLSurfaceANGLE,
-                           AttachmentType::Screen,
-                           gl,
-                           size,
-                           hasAlpha)
-        , mEGL(egl)
-        , mContext(context)
-        , mPBuffer(pbuffer)
-        , mTexture(texture)
-        , mSRV(srv)
-    {}
-
-    EGLDisplay Display();
-
-public:
-    virtual ~SharedSurface_ANGLEShareHandle();
-
-    virtual void LockProdImpl();
-    virtual void UnlockProdImpl();
-
-    virtual void Fence();
-    virtual bool WaitSync();
-
-    // Implementation-specific functions below:
-    ID3D10ShaderResourceView* GetSRV() {
-        return mSRV;
-    }
-};
-
-
-
-class SurfaceFactory_ANGLEShareHandle
-    : public SurfaceFactory_GL
-{
-protected:
-    GLContext* const mProdGL;
-    GLLibraryEGL* const mEGL;
-    nsRefPtr<ID3D10Device1> mConsD3D;
-    EGLContext mContext;
-    EGLConfig mConfig;
-
-public:
-    static SurfaceFactory_ANGLEShareHandle* Create(GLContext* gl,
-                                                   ID3D10Device1* d3d,
-                                                   const SurfaceCaps& caps);
-
-protected:
-    SurfaceFactory_ANGLEShareHandle(GLContext* gl,
-                                    GLLibraryEGL* egl,
-                                    ID3D10Device1* d3d,
-                                    const SurfaceCaps& caps);
-
-    virtual SharedSurface* CreateShared(const gfxIntSize& size) {
-        bool hasAlpha = mReadCaps.alpha;
-        return SharedSurface_ANGLEShareHandle::Create(mProdGL, mConsD3D,
-                                                      mContext, mConfig,
-                                                      size, hasAlpha);
-    }
-};
-
-} /* namespace gfx */
-} /* namespace mozilla */
-
-#endif /* SHARED_SURFACE_ANGLE_H_ */
deleted file mode 100644
--- a/gfx/gl/SharedSurfaceEGL.cpp
+++ /dev/null
@@ -1,262 +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 "SharedSurfaceEGL.h"
-
-#include "GLContext.h"
-#include "SharedSurfaceGL.h"
-#include "SurfaceFactory.h"
-#include "GLLibraryEGL.h"
-
-using namespace mozilla::gfx;
-
-namespace mozilla {
-namespace gl {
-
-SharedSurface_EGLImage*
-SharedSurface_EGLImage::Create(GLContext* prodGL,
-                               const GLFormats& formats,
-                               const gfxIntSize& size,
-                               bool hasAlpha,
-                               EGLContext context)
-{
-    GLLibraryEGL* egl = prodGL->GetLibraryEGL();
-    MOZ_ASSERT(egl);
-
-    if (!HasExtensions(egl, prodGL))
-        return nullptr;
-
-    MOZ_ALWAYS_TRUE(prodGL->MakeCurrent());
-    GLuint prodTex = prodGL->CreateTextureForOffscreen(formats, size);
-    if (!prodTex)
-        return nullptr;
-
-    return new SharedSurface_EGLImage(prodGL, egl,
-                                      size, hasAlpha,
-                                      formats, prodTex);
-}
-
-
-bool
-SharedSurface_EGLImage::HasExtensions(GLLibraryEGL* egl, GLContext* gl)
-{
-    return egl->HasKHRImageBase() &&
-           egl->IsExtensionSupported(GLLibraryEGL::KHR_gl_texture_2D_image) &&
-           gl->IsExtensionSupported(GLContext::OES_EGL_image);
-}
-
-SharedSurface_EGLImage::~SharedSurface_EGLImage()
-{
-    mEGL->fDestroyImage(Display(), mImage);
-    mImage = 0;
-
-    mGL->MakeCurrent();
-    mGL->fDeleteTextures(1, &mProdTex);
-    mProdTex = 0;
-
-    if (mProdTexForPipe) {
-        mGL->fDeleteTextures(1, &mProdTexForPipe);
-        mProdTexForPipe = 0;
-    }
-
-    if (mConsTex) {
-        MOZ_ASSERT(mGarbageBin);
-        mGarbageBin->Trash(mConsTex);
-        mConsTex = 0;
-    }
-
-    if (mSync) {
-        // We can't call this unless we have the ext, but we will always have
-        // the ext if we have something to destroy.
-        mEGL->fDestroySync(Display(), mSync);
-        mSync = 0;
-    }
-}
-
-void
-SharedSurface_EGLImage::LockProdImpl()
-{
-    MutexAutoLock lock(mMutex);
-
-    if (!mPipeComplete)
-        return;
-
-    if (mPipeActive)
-        return;
-
-    mGL->BlitTextureToTexture(mProdTex, mProdTexForPipe, Size(), Size());
-    mGL->fDeleteTextures(1, &mProdTex);
-    mProdTex = mProdTexForPipe;
-    mProdTexForPipe = 0;
-    mPipeActive = true;
-}
-
-static bool
-CreateTexturePipe(GLLibraryEGL* const egl, GLContext* const gl,
-                  const GLFormats& formats, const gfxIntSize& size,
-                  GLuint* const out_tex, EGLImage* const out_image)
-{
-    MOZ_ASSERT(out_tex && out_image);
-    *out_tex = 0;
-    *out_image = 0;
-
-    GLuint tex = gl->CreateTextureForOffscreen(formats, size);
-    if (!tex)
-        return false;
-
-    EGLContext context = gl->GetEGLContext();
-    MOZ_ASSERT(context);
-    EGLClientBuffer buffer = reinterpret_cast<EGLClientBuffer>(tex);
-    EGLImage image = egl->fCreateImage(egl->Display(), context,
-                                       LOCAL_EGL_GL_TEXTURE_2D, buffer,
-                                       nullptr);
-    if (!image) {
-        gl->fDeleteTextures(1, &tex);
-        return false;
-    }
-
-    // Success.
-    *out_tex = tex;
-    *out_image = image;
-    return true;
-}
-
-void
-SharedSurface_EGLImage::Fence()
-{
-    MutexAutoLock lock(mMutex);
-    mGL->MakeCurrent();
-
-    if (!mPipeActive) {
-        MOZ_ASSERT(!mSync);
-        MOZ_ASSERT(!mPipeComplete);
-
-        if (!mPipeFailed) {
-            if (!CreateTexturePipe(mEGL, mGL, mFormats, Size(),
-                                   &mProdTexForPipe, &mImage))
-            {
-                mPipeFailed = true;
-            }
-        }
-
-        if (!mPixels) {
-            gfxASurface::gfxImageFormat format =
-                  HasAlpha() ? gfxASurface::ImageFormatARGB32
-                             : gfxASurface::ImageFormatRGB24;
-            mPixels = new gfxImageSurface(Size(), format);
-        }
-
-        mPixels->Flush();
-        mGL->ReadScreenIntoImageSurface(mPixels);
-        mPixels->MarkDirty();
-        return;
-    }
-    MOZ_ASSERT(mPipeActive);
-    MOZ_ASSERT(mCurConsGL);
-
-    if (mEGL->IsExtensionSupported(GLLibraryEGL::KHR_fence_sync) &&
-        mGL->IsExtensionSupported(GLContext::OES_EGL_sync))
-    {
-        if (mSync) {
-            MOZ_ALWAYS_TRUE( mEGL->fDestroySync(Display(), mSync) );
-            mSync = 0;
-        }
-
-        mSync = mEGL->fCreateSync(Display(),
-                                  LOCAL_EGL_SYNC_FENCE,
-                                  nullptr);
-        if (mSync) {
-            mGL->fFlush();
-            return;
-        }
-    }
-
-    MOZ_ASSERT(!mSync);
-    mGL->fFinish();
-}
-
-bool
-SharedSurface_EGLImage::WaitSync()
-{
-    MutexAutoLock lock(mMutex);
-    if (!mSync) {
-        // We must not be needed.
-        return true;
-    }
-    MOZ_ASSERT(mEGL->IsExtensionSupported(GLLibraryEGL::KHR_fence_sync));
-
-    EGLTime waitMS = 500;
-    const EGLTime nsPerMS = 1000 * 1000;
-    EGLTime waitNS = waitMS * nsPerMS;
-    EGLint status = mEGL->fClientWaitSync(Display(),
-                                          mSync,
-                                          0,
-                                          waitNS);
-
-    if (status != LOCAL_EGL_CONDITION_SATISFIED) {
-        return false;
-    }
-
-    MOZ_ALWAYS_TRUE( mEGL->fDestroySync(Display(), mSync) );
-    mSync = 0;
-
-    return true;
-}
-
-
-EGLDisplay
-SharedSurface_EGLImage::Display() const
-{
-    return mEGL->Display();
-}
-
-GLuint
-SharedSurface_EGLImage::AcquireConsumerTexture(GLContext* consGL)
-{
-    MutexAutoLock lock(mMutex);
-    MOZ_ASSERT(!mCurConsGL || consGL == mCurConsGL);
-    if (mPipeFailed)
-        return 0;
-
-    if (mPipeActive) {
-        MOZ_ASSERT(mConsTex);
-
-        return mConsTex;
-    }
-
-    if (!mConsTex) {
-        consGL->fGenTextures(1, &mConsTex);
-        ScopedBindTexture autoTex(consGL, mConsTex);
-        consGL->fEGLImageTargetTexture2D(LOCAL_GL_TEXTURE_2D, mImage);
-
-        mPipeComplete = true;
-        mCurConsGL = consGL;
-        mGarbageBin = consGL->TexGarbageBin();
-    }
-
-    MOZ_ASSERT(consGL == mCurConsGL);
-    return 0;
-}
-
-gfxImageSurface*
-SharedSurface_EGLImage::GetPixels() const
-{
-    MutexAutoLock lock(mMutex);
-    return mPixels;
-}
-
-
-
-SurfaceFactory_EGLImage*
-SurfaceFactory_EGLImage::Create(GLContext* prodGL,
-                                        const SurfaceCaps& caps)
-{
-    EGLContext context = prodGL->GetEGLContext();
-
-    return new SurfaceFactory_EGLImage(prodGL, context, caps);
-}
-
-} /* namespace gfx */
-} /* namespace mozilla */
deleted file mode 100644
--- a/gfx/gl/SharedSurfaceEGL.h
+++ /dev/null
@@ -1,135 +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/. */
-
-#ifndef SHARED_SURFACE_EGL_H_
-#define SHARED_SURFACE_EGL_H_
-
-#include "SharedSurfaceGL.h"
-#include "SurfaceFactory.h"
-#include "GLLibraryEGL.h"
-#include "SurfaceTypes.h"
-#include "mozilla/Attributes.h"
-#include "mozilla/Mutex.h"
-
-namespace mozilla {
-namespace gl {
-
-class GLContext;
-
-class SharedSurface_EGLImage
-    : public SharedSurface_GL
-{
-public:
-    static SharedSurface_EGLImage* Create(GLContext* prodGL,
-                                                  const GLFormats& formats,
-                                                  const gfxIntSize& size,
-                                                  bool hasAlpha,
-                                                  EGLContext context);
-
-    static SharedSurface_EGLImage* Cast(SharedSurface* surf) {
-        MOZ_ASSERT(surf->Type() == SharedSurfaceType::EGLImageShare);
-
-        return (SharedSurface_EGLImage*)surf;
-    }
-
-protected:
-    mutable Mutex mMutex;
-    GLLibraryEGL* const mEGL;
-    const GLFormats mFormats;
-    GLuint mProdTex;
-    nsRefPtr<gfxImageSurface> mPixels;
-    GLuint mProdTexForPipe; // Moves to mProdTex when mPipeActive becomes true.
-    EGLImage mImage;
-    GLContext* mCurConsGL;
-    GLuint mConsTex;
-    nsRefPtr<TextureGarbageBin> mGarbageBin;
-    EGLSync mSync;
-    bool mPipeFailed;   // Pipe creation failed, and has been abandoned.
-    bool mPipeComplete; // Pipe connects (mPipeActive ? mProdTex : mProdTexForPipe) to mConsTex.
-    bool mPipeActive;   // Pipe is complete and in use for production.
-
-    SharedSurface_EGLImage(GLContext* gl,
-                           GLLibraryEGL* egl,
-                           const gfxIntSize& size,
-                           bool hasAlpha,
-                           const GLFormats& formats,
-                           GLuint prodTex)
-        : SharedSurface_GL(SharedSurfaceType::EGLImageShare,
-                           AttachmentType::GLTexture,
-                           gl,
-                           size,
-                           hasAlpha)
-        , mMutex("SharedSurface_EGLImage mutex")
-        , mEGL(egl)
-        , mFormats(formats)
-        , mProdTex(prodTex)
-        , mProdTexForPipe(0)
-        , mImage(0)
-        , mCurConsGL(nullptr)
-        , mConsTex(0)
-        , mSync(0)
-        , mPipeFailed(false)
-        , mPipeComplete(false)
-        , mPipeActive(false)
-    {}
-
-    EGLDisplay Display() const;
-
-    static bool HasExtensions(GLLibraryEGL* egl, GLContext* gl);
-
-public:
-    virtual ~SharedSurface_EGLImage();
-
-    virtual void LockProdImpl();
-    virtual void UnlockProdImpl() {}
-
-
-    virtual void Fence();
-    virtual bool WaitSync();
-
-
-    virtual GLuint Texture() const {
-        return mProdTex;
-    }
-
-    // Implementation-specific functions below:
-    // Returns 0 if the pipe isn't ready. If 0, use GetPixels below.
-    GLuint AcquireConsumerTexture(GLContext* consGL);
-
-    // Will be void if AcquireConsumerTexture returns non-zero.
-    gfxImageSurface* GetPixels() const;
-};
-
-
-
-class SurfaceFactory_EGLImage
-    : public SurfaceFactory_GL
-{
-public:
-    // Infallible:
-    static SurfaceFactory_EGLImage* Create(GLContext* prodGL,
-                                           const SurfaceCaps& caps);
-
-protected:
-    const EGLContext mContext;
-
-    SurfaceFactory_EGLImage(GLContext* prodGL,
-                            EGLContext context,
-                            const SurfaceCaps& caps)
-        : SurfaceFactory_GL(prodGL, SharedSurfaceType::EGLImageShare, caps)
-        , mContext(context)
-    {}
-
-public:
-    virtual SharedSurface* CreateShared(const gfxIntSize& size) {
-        bool hasAlpha = mReadCaps.alpha;
-        return SharedSurface_EGLImage::Create(mGL, mFormats, size, hasAlpha, mContext);
-    }
-};
-
-} /* namespace gfx */
-} /* namespace mozilla */
-
-#endif /* SHARED_SURFACE_EGL_H_ */
deleted file mode 100644
--- a/gfx/gl/SharedSurfaceGL.cpp
+++ /dev/null
@@ -1,390 +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 "SharedSurfaceGL.h"
-
-#include "GLContext.h"
-#include "gfxImageSurface.h"
-
-using namespace mozilla::gfx;
-
-namespace mozilla {
-namespace gl {
-
-// |src| must begin and end locked, though we may
-// temporarily unlock it if we need to.
-void
-SharedSurface_GL::Copy(SharedSurface_GL* src, SharedSurface_GL* dest,
-                       SurfaceFactory_GL* factory)
-{
-    GLContext* gl = src->GL();
-
-    if (src->AttachType() == AttachmentType::Screen &&
-        dest->AttachType() == AttachmentType::Screen)
-    {
-        // Here, we actually need to blit through a temp surface, so let's make one.
-        nsAutoPtr<SharedSurface_GLTexture> tempSurf(
-            SharedSurface_GLTexture::Create(gl, gl,
-                                            factory->Formats(),
-                                            src->Size(),
-                                            factory->Caps().alpha));
-
-        Copy(src, tempSurf, factory);
-        Copy(tempSurf, dest, factory);
-        return;
-    }
-
-    if (src->AttachType() == AttachmentType::Screen) {
-        SharedSurface* origLocked = gl->GetLockedSurface();
-        bool srcNeedsUnlock = false;
-        bool origNeedsRelock = false;
-        if (origLocked != src) {
-            if (origLocked) {
-                origLocked->UnlockProd();
-                origNeedsRelock = true;
-            }
-
-            src->LockProd();
-            srcNeedsUnlock = true;
-        }
-
-        if (dest->AttachType() == AttachmentType::GLTexture) {
-            GLuint destTex = dest->Texture();
-
-            gl->BlitFramebufferToTexture(0, destTex, src->Size(), dest->Size());
-        } else if (dest->AttachType() == AttachmentType::GLRenderbuffer) {
-            GLuint destRB = dest->Renderbuffer();
-            ScopedFramebufferForRenderbuffer destWrapper(gl, destRB);
-
-            gl->BlitFramebufferToFramebuffer(0, destWrapper.FB(),
-                                             src->Size(), dest->Size());
-        } else {
-            MOZ_NOT_REACHED("Unhandled dest->AttachType().");
-            return;
-        }
-
-        if (srcNeedsUnlock)
-            src->UnlockProd();
-
-        if (origNeedsRelock)
-            origLocked->LockProd();
-
-        return;
-    }
-
-    if (dest->AttachType() == AttachmentType::Screen) {
-        SharedSurface* origLocked = gl->GetLockedSurface();
-        bool destNeedsUnlock = false;
-        bool origNeedsRelock = false;
-        if (origLocked != dest) {
-            if (origLocked) {
-                origLocked->UnlockProd();
-                origNeedsRelock = true;
-            }
-
-            dest->LockProd();
-            destNeedsUnlock = true;
-        }
-
-        if (src->AttachType() == AttachmentType::GLTexture) {
-            GLuint srcTex = src->Texture();
-
-            gl->BlitTextureToFramebuffer(srcTex, 0, src->Size(), dest->Size());
-        } else if (src->AttachType() == AttachmentType::GLRenderbuffer) {
-            GLuint srcRB = src->Renderbuffer();
-            ScopedFramebufferForRenderbuffer srcWrapper(gl, srcRB);
-
-            gl->BlitFramebufferToFramebuffer(srcWrapper.FB(), 0,
-                                             src->Size(), dest->Size());
-        } else {
-            MOZ_NOT_REACHED("Unhandled src->AttachType().");
-            return;
-        }
-
-        if (destNeedsUnlock)
-            dest->UnlockProd();
-
-        if (origNeedsRelock)
-            origLocked->LockProd();
-
-        return;
-    }
-
-    // Alright, done with cases involving Screen types.
-    // Only {src,dest}x{texture,renderbuffer} left.
-
-    if (src->AttachType() == AttachmentType::GLTexture) {
-        GLuint srcTex = src->Texture();
-
-        if (dest->AttachType() == AttachmentType::GLTexture) {
-            GLuint destTex = dest->Texture();
-
-            gl->BlitTextureToTexture(srcTex, destTex,
-                                     src->Size(), dest->Size());
-
-            return;
-        }
-
-        if (dest->AttachType() == AttachmentType::GLRenderbuffer) {
-            GLuint destRB = dest->Renderbuffer();
-            ScopedFramebufferForRenderbuffer destWrapper(gl, destRB);
-
-            gl->BlitTextureToFramebuffer(srcTex, destWrapper.FB(),
-                                         src->Size(), dest->Size());
-
-            return;
-        }
-
-        MOZ_NOT_REACHED("Unhandled dest->AttachType().");
-        return;
-    }
-
-    if (src->AttachType() == AttachmentType::GLRenderbuffer) {
-        GLuint srcRB = src->Renderbuffer();
-        ScopedFramebufferForRenderbuffer srcWrapper(gl, srcRB);
-
-        if (dest->AttachType() == AttachmentType::GLTexture) {
-            GLuint destTex = dest->Texture();
-
-            gl->BlitFramebufferToTexture(srcWrapper.FB(), destTex,
-                                         src->Size(), dest->Size());
-
-            return;
-        }
-
-        if (dest->AttachType() == AttachmentType::GLRenderbuffer) {
-            GLuint destRB = dest->Renderbuffer();
-            ScopedFramebufferForRenderbuffer destWrapper(gl, destRB);
-
-            gl->BlitFramebufferToFramebuffer(srcWrapper.FB(), destWrapper.FB(),
-                                             src->Size(), dest->Size());
-
-            return;
-        }
-
-        MOZ_NOT_REACHED("Unhandled dest->AttachType().");
-        return;
-    }
-
-    MOZ_NOT_REACHED("Unhandled src->AttachType().");
-    return;
-}
-
-void
-SharedSurface_GL::LockProd()
-{
-    MOZ_ASSERT(!mIsLocked);
-
-    LockProdImpl();
-
-    mGL->LockSurface(this);
-    mIsLocked = true;
-}
-
-void
-SharedSurface_GL::UnlockProd()
-{
-    if (!mIsLocked)
-        return;
-
-    UnlockProdImpl();
-
-    mGL->UnlockSurface(this);
-    mIsLocked = false;
-}
-
-
-SurfaceFactory_GL::SurfaceFactory_GL(GLContext* gl,
-                                     SharedSurfaceType type,
-                                     const SurfaceCaps& caps)
-    : SurfaceFactory(type, caps)
-    , mGL(gl)
-    , mFormats(gl->ChooseGLFormats(caps))
-{
-    ChooseBufferBits(caps, mDrawCaps, mReadCaps);
-}
-
-void
-SurfaceFactory_GL::ChooseBufferBits(const SurfaceCaps& caps,
-                                    SurfaceCaps& drawCaps,
-                                    SurfaceCaps& readCaps) const
-{
-    SurfaceCaps screenCaps;
-
-    screenCaps.color = caps.color;
-    screenCaps.alpha = caps.alpha;
-    screenCaps.bpp16 = caps.bpp16;
-
-    screenCaps.depth = caps.depth;
-    screenCaps.stencil = caps.stencil;
-
-    screenCaps.antialias = caps.antialias;
-    screenCaps.preserve = caps.preserve;
-
-    if (caps.antialias) {
-        drawCaps = screenCaps;
-        readCaps.Clear();
-
-        // Color caps need to be duplicated in readCaps.
-        readCaps.color = caps.color;
-        readCaps.alpha = caps.alpha;
-        readCaps.bpp16 = caps.bpp16;
-    } else {
-        drawCaps.Clear();
-        readCaps = screenCaps;
-    }
-}
-
-
-SharedSurface_Basic*
-SharedSurface_Basic::Create(GLContext* gl,
-                            const GLFormats& formats,
-                            const gfxIntSize& size,
-                            bool hasAlpha)
-{
-    gl->MakeCurrent();
-    GLuint tex = gl->CreateTexture(formats.color_texInternalFormat,
-                                   formats.color_texFormat,
-                                   formats.color_texType,
-                                   size);
-
-    gfxASurface::gfxImageFormat format = gfxASurface::ImageFormatRGB24;
-    switch (formats.color_texInternalFormat) {
-    case LOCAL_GL_RGB:
-    case LOCAL_GL_RGB8:
-        if (formats.color_texType == LOCAL_GL_UNSIGNED_SHORT_5_6_5)
-            format = gfxASurface::ImageFormatRGB16_565;
-        else
-            format = gfxASurface::ImageFormatRGB24;
-        break;
-    case LOCAL_GL_RGBA:
-    case LOCAL_GL_RGBA8:
-        format = gfxASurface::ImageFormatARGB32;
-        break;
-    default:
-        MOZ_NOT_REACHED("Unhandled Tex format.");
-        return nullptr;