Backed out changeset 176166c0bae9 (bug 1124394) for b2g device bustage on a CLOSED TREE
authorWes Kocher <wkocher@mozilla.com>
Thu, 29 Jan 2015 14:23:37 -0800
changeset 253713 b556a1f684ed50dfc6f649e22ab4dd7d75aa1c62
parent 253712 5969eb0fe8b534c73afb42c5d382d3198dc68fd5
child 253714 4380ed39de3aa0a0b5c5ac06a5dd7e13d226fa74
push id4610
push userjlund@mozilla.com
push dateMon, 30 Mar 2015 18:32:55 +0000
treeherdermozilla-beta@4df54044d9ef [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
bugs1124394
milestone38.0a1
backs out176166c0bae9ee2faea56e45f78598219503d9d8
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 176166c0bae9 (bug 1124394) for b2g device bustage on a CLOSED TREE
dom/canvas/WebGLContext.cpp
dom/canvas/WebGLContext.h
dom/canvas/WebGLContextGL.cpp
dom/canvas/WebGLContextUtils.cpp
dom/canvas/WebGLContextValidate.cpp
dom/media/fmp4/android/AndroidDecoderModule.cpp
dom/plugins/base/nsNPAPIPluginInstance.cpp
gfx/gl/GLContext.cpp
gfx/gl/GLContext.h
gfx/gl/GLContextCGL.h
gfx/gl/GLContextFeatures.cpp
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/GLLibraryEGL.cpp
gfx/gl/GLLibraryEGL.h
gfx/layers/GLImages.cpp
gfx/layers/opengl/CompositorOGL.cpp
gfx/tests/gtest/TestCompositor.cpp
gfx/thebes/gfxPlatform.cpp
widget/android/GfxInfo.cpp
--- a/dom/canvas/WebGLContext.cpp
+++ b/dom/canvas/WebGLContext.cpp
@@ -500,73 +500,73 @@ IsFeatureInBlacklist(const nsCOMPtr<nsIG
     if (!NS_SUCCEEDED(gfxInfo->GetFeatureStatus(feature, &status)))
         return false;
 
     return status != nsIGfxInfo::FEATURE_STATUS_OK;
 }
 
 static already_AddRefed<GLContext>
 CreateHeadlessNativeGL(bool forceEnabled, const nsCOMPtr<nsIGfxInfo>& gfxInfo,
-                       bool requireCompatProfile, WebGLContext* webgl)
+                       WebGLContext* webgl)
 {
     if (!forceEnabled &&
         IsFeatureInBlacklist(gfxInfo, nsIGfxInfo::FEATURE_WEBGL_OPENGL))
     {
         webgl->GenerateWarning("Refused to create native OpenGL context"
                                " because of blacklisting.");
         return nullptr;
     }
 
-    nsRefPtr<GLContext> gl = gl::GLContextProvider::CreateHeadless(requireCompatProfile);
+    nsRefPtr<GLContext> gl = gl::GLContextProvider::CreateHeadless();
     if (!gl) {
         webgl->GenerateWarning("Error during native OpenGL init.");
         return nullptr;
     }
     MOZ_ASSERT(!gl->IsANGLE());
 
     return gl.forget();
 }
 
 // Note that we have a separate call for ANGLE and EGL, even though
 // right now, we get ANGLE implicitly by using EGL on Windows.
 // Eventually, we want to be able to pick ANGLE-EGL or native EGL.
 static already_AddRefed<GLContext>
 CreateHeadlessANGLE(bool forceEnabled, const nsCOMPtr<nsIGfxInfo>& gfxInfo,
-                    bool requireCompatProfile, WebGLContext* webgl)
+                    WebGLContext* webgl)
 {
     nsRefPtr<GLContext> gl;
 
 #ifdef XP_WIN
     if (!forceEnabled &&
         IsFeatureInBlacklist(gfxInfo, nsIGfxInfo::FEATURE_WEBGL_ANGLE))
     {
         webgl->GenerateWarning("Refused to create ANGLE OpenGL context"
                                " because of blacklisting.");
         return nullptr;
     }
 
-    gl = gl::GLContextProviderEGL::CreateHeadless(requireCompatProfile);
+    gl = gl::GLContextProviderEGL::CreateHeadless();
     if (!gl) {
         webgl->GenerateWarning("Error during ANGLE OpenGL init.");
         return nullptr;
     }
     MOZ_ASSERT(gl->IsANGLE());
 #endif
 
     return gl.forget();
 }
 
 static already_AddRefed<GLContext>
-CreateHeadlessEGL(bool forceEnabled, bool requireCompatProfile,
+CreateHeadlessEGL(bool forceEnabled, const nsCOMPtr<nsIGfxInfo>& gfxInfo,
                   WebGLContext* webgl)
 {
     nsRefPtr<GLContext> gl;
 
 #ifdef ANDROID
-    gl = gl::GLContextProviderEGL::CreateHeadless(requireCompatProfile);
+    gl = gl::GLContextProviderEGL::CreateHeadless();
     if (!gl) {
         webgl->GenerateWarning("Error during EGL OpenGL init.");
         return nullptr;
     }
     MOZ_ASSERT(!gl->IsANGLE());
 #endif
 
     return gl.forget();
@@ -578,32 +578,26 @@ CreateHeadlessGL(bool forceEnabled, cons
                  WebGLContext* webgl)
 {
     bool preferEGL = PR_GetEnv("MOZ_WEBGL_PREFER_EGL");
     bool disableANGLE = Preferences::GetBool("webgl.disable-angle", false);
 
     if (PR_GetEnv("MOZ_WEBGL_FORCE_OPENGL"))
         disableANGLE = true;
 
-    bool requireCompatProfile = webgl->IsWebGL2() ? false : true;
-
     nsRefPtr<GLContext> gl;
 
     if (preferEGL)
-        gl = CreateHeadlessEGL(forceEnabled, requireCompatProfile, webgl);
+        gl = CreateHeadlessEGL(forceEnabled, gfxInfo, webgl);
 
-    if (!gl && !disableANGLE) {
-        gl = CreateHeadlessANGLE(forceEnabled, gfxInfo, requireCompatProfile,
-                                 webgl);
-    }
+    if (!gl && !disableANGLE)
+        gl = CreateHeadlessANGLE(forceEnabled, gfxInfo, webgl);
 
-    if (!gl) {
-        gl = CreateHeadlessNativeGL(forceEnabled, gfxInfo,
-                                    requireCompatProfile, webgl);
-    }
+    if (!gl)
+        gl = CreateHeadlessNativeGL(forceEnabled, gfxInfo, webgl);
 
     return gl.forget();
 }
 
 // Try to create a dummy offscreen with the given caps.
 static bool
 CreateOffscreenWithCaps(GLContext* gl, const SurfaceCaps& caps)
 {
--- a/dom/canvas/WebGLContext.h
+++ b/dom/canvas/WebGLContext.h
@@ -1204,20 +1204,19 @@ protected:
     bool IsExtensionSupported(WebGLExtensionID ext) const;
 
     static const char* GetExtensionString(WebGLExtensionID ext);
 
     nsTArray<GLenum> mCompressedTextureFormats;
 
     // -------------------------------------------------------------------------
     // WebGL 2 specifics (implemented in WebGL2Context.cpp)
-public:
+
     virtual bool IsWebGL2() const = 0;
 
-protected:
     bool InitWebGL2();
 
     // -------------------------------------------------------------------------
     // Validation functions (implemented in WebGLContextValidate.cpp)
     bool CreateOffscreenGL(bool forceEnabled);
     bool InitAndValidateGL();
     bool ResizeBackbuffer(uint32_t width, uint32_t height);
     bool ValidateBlendEquationEnum(GLenum cap, const char* info);
--- a/dom/canvas/WebGLContextGL.cpp
+++ b/dom/canvas/WebGLContextGL.cpp
@@ -2102,16 +2102,17 @@ WebGLContext::ReadPixels(GLint x, GLint 
                      + bytesPerPixel * subrect_x_in_dest_buffer, // destination
                    subrect_data.get() + subrect_alignedRowSize * y_inside_subrect, // source
                    subrect_plainRowSize); // size
         }
     }
 
     // if we're reading alpha, we may need to do fixup.  Note that we don't allow
     // GL_ALPHA to readpixels currently, but we had the code written for it already.
+
     const bool formatHasAlpha = format == LOCAL_GL_ALPHA ||
                                 format == LOCAL_GL_RGBA;
     if (!formatHasAlpha)
         return;
 
     bool needAlphaFilled;
     if (mBoundReadFramebuffer) {
         needAlphaFilled = !mBoundReadFramebuffer->ColorAttachment(0).HasAlpha();
--- a/dom/canvas/WebGLContextUtils.cpp
+++ b/dom/canvas/WebGLContextUtils.cpp
@@ -1112,22 +1112,21 @@ WebGLContext::AssertCachedState()
 
     GLfloat depthClearValue = 0.0f;
     gl->fGetFloatv(LOCAL_GL_DEPTH_CLEAR_VALUE, &depthClearValue);
     MOZ_ASSERT(IsCacheCorrect(mDepthClearValue, depthClearValue));
 
     AssertUintParamCorrect(gl, LOCAL_GL_STENCIL_CLEAR_VALUE, mStencilClearValue);
 
     GLint stencilBits = 0;
-    if (GetStencilBits(&stencilBits)) {
-        const GLuint stencilRefMask = (1 << stencilBits) - 1;
+    gl->fGetIntegerv(LOCAL_GL_STENCIL_BITS, &stencilBits);
+    const GLuint stencilRefMask = (1 << stencilBits) - 1;
 
-        AssertMaskedUintParamCorrect(gl, LOCAL_GL_STENCIL_REF,      stencilRefMask, mStencilRefFront);
-        AssertMaskedUintParamCorrect(gl, LOCAL_GL_STENCIL_BACK_REF, stencilRefMask, mStencilRefBack);
-    }
+    AssertMaskedUintParamCorrect(gl, LOCAL_GL_STENCIL_REF,      stencilRefMask, mStencilRefFront);
+    AssertMaskedUintParamCorrect(gl, LOCAL_GL_STENCIL_BACK_REF, stencilRefMask, mStencilRefBack);
 
     AssertUintParamCorrect(gl, LOCAL_GL_STENCIL_VALUE_MASK,      mStencilValueMaskFront);
     AssertUintParamCorrect(gl, LOCAL_GL_STENCIL_BACK_VALUE_MASK, mStencilValueMaskBack);
 
     AssertUintParamCorrect(gl, LOCAL_GL_STENCIL_WRITEMASK,      mStencilWriteMaskFront);
     AssertUintParamCorrect(gl, LOCAL_GL_STENCIL_BACK_WRITEMASK, mStencilWriteMaskBack);
 
     // Viewport
--- a/dom/canvas/WebGLContextValidate.cpp
+++ b/dom/canvas/WebGLContextValidate.cpp
@@ -1774,18 +1774,18 @@ WebGLContext::InitAndValidateGL()
     mCurrentProgram = nullptr;
 
     mBoundDrawFramebuffer = nullptr;
     mBoundReadFramebuffer = nullptr;
     mBoundRenderbuffer = nullptr;
 
     MakeContextCurrent();
 
-    // For OpenGL compat. profiles, we always keep vertex attrib 0 array enabled.
-    if (gl->IsCompatibilityProfile())
+    // on desktop OpenGL, we always keep vertex attrib 0 array enabled
+    if (!gl->IsGLES())
         gl->fEnableVertexAttribArray(0);
 
     if (MinCapabilityMode())
         mGLMaxVertexAttribs = MINVALUE_GL_MAX_VERTEX_ATTRIBS;
     else
         gl->fGetIntegerv(LOCAL_GL_MAX_VERTEX_ATTRIBS, &mGLMaxVertexAttribs);
 
     if (mGLMaxVertexAttribs < 8) {
@@ -1884,17 +1884,17 @@ WebGLContext::InitAndValidateGL()
                 // maxVertexOutputComponents in the OpenGL 3.2 spec.
             }
         }
     }
 
     // Always 1 for GLES2
     mMaxFramebufferColorAttachments = 1;
 
-    if (gl->IsCompatibilityProfile()) {
+    if (!gl->IsGLES()) {
         // gl_PointSize is always available in ES2 GLSL, but has to be
         // specifically enabled on desktop GLSL.
         gl->fEnable(LOCAL_GL_VERTEX_PROGRAM_POINT_SIZE);
 
         /* gl_PointCoord is always available in ES2 GLSL and in newer desktop
          * GLSL versions, but apparently not in OpenGL 2 and apparently not (due
          * to a driver bug) on certain NVIDIA setups. See:
          *   http://www.opengl.org/discussion_boards/ubbthreads.php?ubb=showflat&Number=261472
--- a/dom/media/fmp4/android/AndroidDecoderModule.cpp
+++ b/dom/media/fmp4/android/AndroidDecoderModule.cpp
@@ -168,17 +168,17 @@ public:
   }
 
 protected:
   bool EnsureGLContext() {
     if (mGLContext) {
       return true;
     }
 
-    mGLContext = GLContextProvider::CreateHeadless(false);
+    mGLContext = GLContextProvider::CreateHeadless();
     return mGLContext;
   }
 
   layers::ImageContainer* mImageContainer;
   const mp4_demuxer::VideoDecoderConfig& mConfig;
   RefPtr<AndroidSurfaceTexture> mSurfaceTexture;
   nsRefPtr<GLContext> mGLContext;
 };
--- a/dom/plugins/base/nsNPAPIPluginInstance.cpp
+++ b/dom/plugins/base/nsNPAPIPluginInstance.cpp
@@ -86,18 +86,19 @@ private:
   bool mCanceled;
 };
 
 static nsRefPtr<GLContext> sPluginContext = nullptr;
 
 static bool EnsureGLContext()
 {
   if (!sPluginContext) {
-    bool requireCompatProfile = true;
-    sPluginContext = GLContextProvider::CreateHeadless(requireCompatProfile);
+    gfxIntSize dummySize(16, 16);
+    sPluginContext = GLContextProvider::CreateOffscreen(dummySize,
+                                                        SurfaceCaps::Any());
   }
 
   return sPluginContext != nullptr;
 }
 
 class SharedPluginTexture MOZ_FINAL {
 public:
   NS_INLINE_DECL_REFCOUNTING(SharedPluginTexture)
--- a/gfx/gl/GLContext.cpp
+++ b/gfx/gl/GLContext.cpp
@@ -3,17 +3,16 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include <algorithm>
 #include <stdio.h>
 #include <string.h>
 #include <ctype.h>
-#include <vector>
 
 #include "GLContext.h"
 #include "GLBlitHelper.h"
 #include "GLReadTexImageHelper.h"
 
 #include "gfxCrashReporterUtils.h"
 #include "gfxUtils.h"
 #include "GLContextProvider.h"
@@ -152,17 +151,18 @@ static const char *sExtensionNames[] = {
     "GL_OES_standard_derivatives",
     "GL_OES_stencil8",
     "GL_OES_texture_3D",
     "GL_OES_texture_float",
     "GL_OES_texture_float_linear",
     "GL_OES_texture_half_float",
     "GL_OES_texture_half_float_linear",
     "GL_OES_texture_npot",
-    "GL_OES_vertex_array_object"
+    "GL_OES_vertex_array_object",
+    nullptr
 };
 
 static bool
 ParseGLVersion(GLContext* gl, uint32_t* out_version)
 {
     if (gl->fGetError() != LOCAL_GL_NO_ERROR) {
         MOZ_ASSERT(false, "An OpenGL error has been triggered before.");
         return false;
@@ -312,18 +312,16 @@ GLContext::~GLContext() {
         while (tip->mSharedContext)
             tip = tip->mSharedContext;
         tip->SharedContextDestroyed(this);
         tip->ReportOutstandingNames();
     } else {
         ReportOutstandingNames();
     }
 #endif
-
-    DeleteAndClearIterable(mDriverExtensionList);
 }
 
 /*static*/ void
 GLContext::StaticDebugCallback(GLenum source,
                                GLenum type,
                                GLuint id,
                                GLenum severity,
                                GLsizei length,
@@ -498,18 +496,16 @@ GLContext::InitWithPrefix(const char *pr
 
         END_SYMBOLS
 
     };
 
     mInitialized = LoadSymbols(&symbols[0], trygl, prefix);
     MakeCurrent();
     if (mInitialized) {
-        MOZ_ASSERT(mProfile != ContextProfile::Unknown);
-
         uint32_t version = 0;
         ParseGLVersion(this, &version);
 
         if (ShouldSpew()) {
             printf_stderr("OpenGL version detected: %u\n", version);
             printf_stderr("OpenGL vendor: %s\n", fGetString(LOCAL_GL_VENDOR));
             printf_stderr("OpenGL renderer: %s\n", fGetString(LOCAL_GL_RENDERER));
         }
@@ -655,39 +651,36 @@ GLContext::InitWithPrefix(const char *pr
             if (mVendor < GLVendor::Other) {
                 printf_stderr("OpenGL vendor ('%s') recognized as: %s\n",
                               glVendorString, vendors[size_t(mVendor)]);
             } else {
                 printf_stderr("OpenGL vendor ('%s') unrecognized\n", glVendorString);
             }
         }
 
-        if (IsFeatureProvidedByCoreSymbols(GLFeature::get_string_indexed)) {
-            SymLoadStruct moreSymbols[] = {
-                { (PRFuncPtr*) &mSymbols.fGetStringi,    { "GetStringi", nullptr } },
-                END_SYMBOLS
-            };
-
-            MOZ_ALWAYS_TRUE(LoadSymbols(moreSymbols, trygl, prefix));
-        }
-
         InitExtensions();
         InitFeatures();
 
         // Disable extensions with partial or incorrect support.
         if (WorkAroundDriverBugs()) {
             if (Renderer() == GLRenderer::AdrenoTM320) {
                 MarkUnsupported(GLFeature::standard_derivatives);
             }
 
             if (Vendor() == GLVendor::Vivante) {
                 // bug 958256
                 MarkUnsupported(GLFeature::standard_derivatives);
             }
 
+            if (Vendor() == GLVendor::Imagination &&
+                Renderer() == GLRenderer::SGX540) {
+                // Bug 980048
+                MarkExtensionUnsupported(OES_EGL_sync);
+            }
+
             if (Renderer() == GLRenderer::MicrosoftBasicRenderDriver) {
                 // Bug 978966: on Microsoft's "Basic Render Driver" (software renderer)
                 // multisampling hardcodes blending with the default blendfunc, which breaks WebGL.
                 MarkUnsupported(GLFeature::framebuffer_multisample);
             }
 
 #ifdef XP_MACOSX
             // The Mac Nvidia driver, for versions up to and including 10.8,
@@ -1470,23 +1463,20 @@ GLContext::InitWithPrefix(const char *pr
         mMaxSamples = 0;
         if (IsSupported(GLFeature::framebuffer_multisample)) {
             fGetIntegerv(LOCAL_GL_MAX_SAMPLES, (GLint*)&mMaxSamples);
         }
 
         // We're ready for final setup.
         fBindFramebuffer(LOCAL_GL_FRAMEBUFFER, 0);
 
-        // TODO: Remove SurfaceCaps::any.
-        if (mCaps.any) {
-            mCaps.any = false;
-            mCaps.color = true;
-            mCaps.alpha = false;
-        }
+        if (mCaps.any)
+            DetermineCaps();
 
+        UpdatePixelFormat();
         UpdateGLFormats(mCaps);
 
         mTexGarbageBin = new TextureGarbageBin(this);
 
         MOZ_ASSERT(IsCurrent());
 
         if (DebugMode() && IsExtensionSupported(KHR_debug)) {
             fEnable(LOCAL_GL_DEBUG_OUTPUT);
@@ -1598,111 +1588,71 @@ GLContext::DebugCallback(GLenum source,
                   typeStr.BeginReading(),
                   sevStr.BeginReading(),
                   message);
 }
 
 void
 GLContext::InitExtensions()
 {
-    MOZ_ASSERT(IsCurrent());
+    MakeCurrent();
+    const char* extensions = (const char*)fGetString(LOCAL_GL_EXTENSIONS);
+    if (!extensions)
+        return;
 
-    if (IsFeatureProvidedByCoreSymbols(GLFeature::get_string_indexed)) {
-        GLuint count = 0;
-        GetUIntegerv(LOCAL_GL_NUM_EXTENSIONS, &count);
-        for (GLuint i = 0; i < count; i++) {
-            // This is UTF-8.
-            const char* rawExt = (const char*)fGetStringi(LOCAL_GL_EXTENSIONS,
-                                                          i);
-            nsACString* ext = new nsDependentCString(rawExt);
-            mDriverExtensionList.push_back(ext);
-        }
-    } else {
-        MOZ_ALWAYS_TRUE(!fGetError());
-        const char* rawExts = (const char*)fGetString(LOCAL_GL_EXTENSIONS);
-        MOZ_ALWAYS_TRUE(!fGetError());
+    InitializeExtensionsBitSet(mAvailableExtensions, extensions,
+                               sExtensionNames);
 
-        if (rawExts) {
-            nsDependentCString exts(rawExts);
-            SplitByChar(exts, ' ', &mDriverExtensionList);
-        }
+    if (WorkAroundDriverBugs() &&
+        Vendor() == GLVendor::Qualcomm) {
+
+        // Some Adreno drivers do not report GL_OES_EGL_sync, but they really do support it.
+        MarkExtensionSupported(OES_EGL_sync);
     }
 
-    const bool shouldDumpExts = ShouldDumpExts();
-    if (shouldDumpExts) {
-        printf_stderr("%i GL driver extensions:\n",
-                      (uint32_t)mDriverExtensionList.size());
+    if (WorkAroundDriverBugs() &&
+        Renderer() == GLRenderer::AndroidEmulator) {
+        // the Android emulator, which we use to run B2G reftests on,
+        // doesn't expose the OES_rgb8_rgba8 extension, but it seems to
+        // support it (tautologically, as it only runs on desktop GL).
+        MarkExtensionSupported(OES_rgb8_rgba8);
     }
 
-    MarkBitfieldByStrings(mDriverExtensionList, shouldDumpExts, sExtensionNames,
-                          mAvailableExtensions);
-
-    if (WorkAroundDriverBugs()) {
-        if (Vendor() == GLVendor::Qualcomm) {
-            // Some Adreno drivers do not report GL_OES_EGL_sync, but they really do support it.
-            MarkExtensionSupported(OES_EGL_sync);
-        }
-
-        if (Vendor() == GLVendor::Imagination &&
-            Renderer() == GLRenderer::SGX540)
-        {
-            // Bug 980048
-            MarkExtensionUnsupported(OES_EGL_sync);
-        }
-
-        if (Renderer() == GLRenderer::AndroidEmulator) {
-            // the Android emulator, which we use to run B2G reftests on,
-            // doesn't expose the OES_rgb8_rgba8 extension, but it seems to
-            // support it (tautologically, as it only runs on desktop GL).
-            MarkExtensionSupported(OES_rgb8_rgba8);
-        }
-
-        if (Vendor() == GLVendor::VMware &&
-            Renderer() == GLRenderer::GalliumLlvmpipe)
-        {
-            // The llvmpipe driver that is used on linux try servers appears to have
-            // buggy support for s3tc/dxt1 compressed textures.
-            // See Bug 975824.
-            MarkExtensionUnsupported(EXT_texture_compression_s3tc);
-            MarkExtensionUnsupported(EXT_texture_compression_dxt1);
-            MarkExtensionUnsupported(ANGLE_texture_compression_dxt3);
-            MarkExtensionUnsupported(ANGLE_texture_compression_dxt5);
-        }
+    if (WorkAroundDriverBugs() &&
+        Vendor() == GLVendor::VMware &&
+        Renderer() == GLRenderer::GalliumLlvmpipe)
+    {
+        // The llvmpipe driver that is used on linux try servers appears to have
+        // buggy support for s3tc/dxt1 compressed textures.
+        // See Bug 975824.
+        MarkExtensionUnsupported(EXT_texture_compression_s3tc);
+        MarkExtensionUnsupported(EXT_texture_compression_dxt1);
+        MarkExtensionUnsupported(ANGLE_texture_compression_dxt3);
+        MarkExtensionUnsupported(ANGLE_texture_compression_dxt5);
+    }
 
 #ifdef XP_MACOSX
-        // Bug 1009642: On OSX Mavericks (10.9), the driver for Intel HD
-        // 3000 appears to be buggy WRT updating sub-images of S3TC
-        // textures with glCompressedTexSubImage2D. Works on Intel HD 4000
-        // and Intel HD 5000/Iris that I tested.
-        if (nsCocoaFeatures::OSXVersionMajor() == 10 &&
-            nsCocoaFeatures::OSXVersionMinor() == 9 &&
-            Renderer() == GLRenderer::IntelHD3000)
-        {
-            MarkExtensionUnsupported(EXT_texture_compression_s3tc);
-        }
-#endif
+    // Bug 1009642: On OSX Mavericks (10.9), the driver for Intel HD
+    // 3000 appears to be buggy WRT updating sub-images of S3TC
+    // textures with glCompressedTexSubImage2D. Works on Intel HD 4000
+    // and Intel HD 5000/Iris that I tested.
+    if (WorkAroundDriverBugs() &&
+        nsCocoaFeatures::OSXVersionMajor() == 10 &&
+        nsCocoaFeatures::OSXVersionMinor() == 9 &&
+        Renderer() == GLRenderer::IntelHD3000)
+    {
+        MarkExtensionUnsupported(EXT_texture_compression_s3tc);
     }
-
-    if (shouldDumpExts) {
-        printf_stderr("\nActivated extensions:\n");
-
-        for (size_t i = 0; i < mAvailableExtensions.size(); i++) {
-            if (!mAvailableExtensions[i])
-                continue;
-
-            const char* ext = sExtensionNames[i];
-            printf_stderr("[%i] %s\n", (uint32_t)i, ext);
-        }
-    }
+#endif
 }
 
 void
 GLContext::PlatformStartup()
 {
-    RegisterStrongMemoryReporter(new GfxTexturesReporter());
+  RegisterStrongMemoryReporter(new GfxTexturesReporter());
 }
 
 // Common code for checking for both GL extensions and GLX extensions.
 bool
 GLContext::ListHasExtension(const GLubyte *extensions, const char *extension)
 {
     // fix bug 612572 - we were crashing as we were calling this function with extensions==null
     if (extensions == nullptr || extension == nullptr)
@@ -1733,16 +1683,76 @@ GLContext::ListHasExtension(const GLubyt
                 return true;
             }
         }
         start = terminator;
     }
     return false;
 }
 
+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 MOZ_GL_DEBUG
+    const SurfaceCaps& caps = Caps();
+    MOZ_ASSERT(!caps.any, "Did you forget to DetermineCaps()?");
+
+    MOZ_ASSERT(caps.color == !!format.red);
+    MOZ_ASSERT(caps.color == !!format.green);
+    MOZ_ASSERT(caps.color == !!format.blue);
+
+    // These we either must have if they're requested, or
+    // we can have if they're not.
+    MOZ_ASSERT(caps.alpha == !!format.alpha || !caps.alpha);
+    MOZ_ASSERT(caps.depth == !!format.depth || !caps.depth);
+    MOZ_ASSERT(caps.stencil == !!format.stencil || !caps.stencil);
+
+    MOZ_ASSERT(caps.antialias == (format.samples > 1));
+#endif
+    mPixelFormat = new PixelBufferFormat(format);
+}
+
 GLFormats
 GLContext::ChooseGLFormats(const SurfaceCaps& caps) const
 {
     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;
@@ -2402,22 +2412,16 @@ GLContext::FlushIfHeavyGLCallsSinceLastF
 {
     if (!mHeavyGLCallsSinceLastFlush) {
         return;
     }
     MakeCurrent();
     fFlush();
 }
 
-/*static*/ bool
-GLContext::ShouldDumpExts()
-{
-    return PR_GetEnv("MOZ_GL_DUMP_EXTS");
-}
-
 bool
 DoesStringMatch(const char* aString, const char *aWantedString)
 {
     if (!aString || !aWantedString)
         return false;
 
     const char *occurrence = strstr(aString, aWantedString);
 
@@ -2439,32 +2443,10 @@ DoesStringMatch(const char* aString, con
 
 /*static*/ bool
 GLContext::ShouldSpew()
 {
     static bool spew = PR_GetEnv("MOZ_GL_SPEW");
     return spew;
 }
 
-void
-SplitByChar(const nsACString& str, const char delim,
-            std::vector<nsACString*>* out)
-{
-    uint32_t start = 0;
-    while (true) {
-        int32_t end = str.FindChar(' ', start);
-        if (end == -1)
-            break;
-
-        uint32_t len = (uint32_t)end - start;
-        nsACString* substr = new nsDependentCSubstring(str, start, len);
-        out->push_back(substr);
-
-        start = end + 1;
-        continue;
-    }
-
-    nsACString* substr = new nsDependentCSubstring(str, start);
-    out->push_back(substr);
-}
-
 } /* namespace gl */
 } /* namespace mozilla */
--- a/gfx/gl/GLContext.h
+++ b/gfx/gl/GLContext.h
@@ -99,17 +99,16 @@ enum class GLFeature {
     frag_color_float,
     frag_depth,
     framebuffer_blit,
     framebuffer_multisample,
     framebuffer_object,
     get_integer_indexed,
     get_integer64_indexed,
     get_query_object_iv,
-    get_string_indexed,
     gpu_shader4,
     instanced_arrays,
     instanced_non_arrays,
     invalidate_framebuffer,
     map_buffer_range,
     occlusion_query,
     occlusion_query_boolean,
     occlusion_query2,
@@ -304,38 +303,36 @@ public:
         return false;
     }
 
     virtual GLContextType GetContextType() const = 0;
 
     virtual bool IsCurrent() = 0;
 
 protected:
+
     bool mInitialized;
     bool mIsOffscreen;
     bool mIsGlobalSharedContext;
     bool mContextLost;
 
     /**
      * mVersion store the OpenGL's version, multiplied by 100. For example, if
      * the context is an OpenGL 2.1 context, mVersion value will be 210.
      */
     uint32_t mVersion;
     nsCString mVersionString;
     ContextProfile mProfile;
 
     GLVendor mVendor;
     GLRenderer mRenderer;
 
-    void SetProfileVersion(ContextProfile profile, uint32_t version) {
-        MOZ_ASSERT(!mInitialized, "SetProfileVersion can only be called before"
-                                  " initialization!");
-        MOZ_ASSERT(profile != ContextProfile::Unknown &&
-                   profile != ContextProfile::OpenGL,
-                   "Invalid `profile` for SetProfileVersion");
+    inline void SetProfileVersion(ContextProfile profile, unsigned int version) {
+        MOZ_ASSERT(!mInitialized, "SetProfileVersion can only be called before initialization!");
+        MOZ_ASSERT(profile != ContextProfile::Unknown && profile != ContextProfile::OpenGL, "Invalid `profile` for SetProfileVersion");
         MOZ_ASSERT(version >= 100, "Invalid `version` for SetProfileVersion");
 
         mVersion = version;
         mProfile = profile;
     }
 
 
 // -----------------------------------------------------------------------------
@@ -455,25 +452,60 @@ public:
         Extensions_Max,
         Extensions_End
     };
 
     bool IsExtensionSupported(GLExtensions aKnownExtension) const {
         return mAvailableExtensions[aKnownExtension];
     }
 
-protected:
     void MarkExtensionUnsupported(GLExtensions aKnownExtension) {
         mAvailableExtensions[aKnownExtension] = 0;
     }
 
     void MarkExtensionSupported(GLExtensions aKnownExtension) {
         mAvailableExtensions[aKnownExtension] = 1;
     }
 
+public:
+    template<size_t N>
+    static void InitializeExtensionsBitSet(std::bitset<N>& extensionsBitset,
+                                           const char* extStr,
+                                           const char** extList)
+    {
+        char* exts = ::strdup(extStr);
+
+        if (ShouldSpew())
+            printf_stderr("Extensions: %s\n", exts);
+
+        char* cur = exts;
+        bool done = false;
+        while (!done) {
+            char* space = strchr(cur, ' ');
+            if (space) {
+                *space = '\0';
+            } else {
+                done = true;
+            }
+
+            for (int i = 0; extList[i]; ++i) {
+                if (PL_strcasecmp(cur, extList[i]) == 0) {
+                    if (ShouldSpew())
+                        printf_stderr("Found extension %s\n", cur);
+                    extensionsBitset[i] = true;
+                }
+            }
+
+            cur = space + 1;
+        }
+
+        free(exts);
+    }
+
+protected:
     std::bitset<Extensions_Max> mAvailableExtensions;
 
 // -----------------------------------------------------------------------------
 // Feature queries
 /*
  * This mecahnism introduces a new way to check if a OpenGL feature is
  * supported, regardless of whether it is supported by an extension or natively
  * by the context version/profile
@@ -3144,27 +3176,16 @@ public:
         mSymbols.fCompressedTexSubImage3D(target, level,
                                           xoffset, yoffset, zoffset,
                                           width, height, depth,
                                           format, imageSize, data);
         AFTER_GL_CALL;
     }
 
 // -----------------------------------------------------------------------------
-// get_string_indexed
-
-    const GLubyte* fGetStringi(GLenum name, GLuint index) {
-        BEFORE_GL_CALL;
-        ASSERT_SYMBOL_PRESENT(fGetStringi);
-        const GLubyte* ret = mSymbols.fGetStringi(name, index);
-        AFTER_GL_CALL;
-        return ret;
-    }
-
-// -----------------------------------------------------------------------------
 // Constructor
 protected:
     explicit GLContext(const SurfaceCaps& caps,
                        GLContext* sharedContext = nullptr,
                        bool isOffscreen = false);
 
 
 // -----------------------------------------------------------------------------
@@ -3422,19 +3443,21 @@ public:
             return false;
 
         MakeCurrent();
         fBindFramebuffer(LOCAL_GL_FRAMEBUFFER, 0);
         fScissor(0, 0, size.width, size.height);
         fViewport(0, 0, size.width, size.height);
 
         mCaps = mScreen->mCaps;
-        MOZ_ASSERT(!mCaps.any);
+        if (mCaps.any)
+            DetermineCaps();
 
         UpdateGLFormats(mCaps);
+        UpdatePixelFormat();
 
         return true;
     }
 
 protected:
     // Note that it does -not- clear the resized buffers.
     bool CreateScreenBuffer(const gfx::IntSize& size, const SurfaceCaps& caps) {
         if (!IsOffscreenSizeAllowed(size))
@@ -3447,33 +3470,43 @@ protected:
                                 const SurfaceCaps& caps);
 
 public:
     bool ResizeScreenBuffer(const gfx::IntSize& size);
 
 protected:
     SurfaceCaps mCaps;
     nsAutoPtr<GLFormats> mGLFormats;
+    nsAutoPtr<PixelBufferFormat> mPixelFormat;
 
 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;
+    }
+
     bool IsFramebufferComplete(GLuint fb, GLenum* status = nullptr);
 
     // Does not check completeness.
     void AttachBuffersToFB(GLuint colorTex, GLuint colorRB,
                            GLuint depthRB, GLuint stencilRB,
                            GLuint fb, GLenum target = LOCAL_GL_TEXTURE_2D);
 
     // Passing null is fine if the value you'd get is 0.
@@ -3503,17 +3536,17 @@ public:
         mLockedSurface = nullptr;
     }
 
     SharedSurface* GetLockedSurface() const {
         return mLockedSurface;
     }
 
     bool IsOffscreen() const {
-        return mIsOffscreen;
+        return mScreen;
     }
 
     GLScreenBuffer* Screen() const {
         return mScreen.get();
     }
 
     /* Clear to transparent black, with 0 depth and stencil,
      * while preserving current ClearColor etc. values.
@@ -3540,18 +3573,16 @@ public:
 
     bool IsOffscreenSizeAllowed(const gfx::IntSize& aSize) const;
 
 protected:
     bool InitWithPrefix(const char *prefix, bool trygl);
 
     void InitExtensions();
 
-    std::vector<nsACString*> mDriverExtensionList;
-
     GLint mViewportRect[4];
     GLint mScissorRect[4];
 
     GLint mMaxTextureSize;
     GLint mMaxCubeMapTextureSize;
     GLint mMaxTextureImageSize;
     GLint mMaxRenderbufferSize;
     GLint mMaxViewportDims[2];
@@ -3660,62 +3691,17 @@ public:
 
 
 protected:
     bool mHeavyGLCallsSinceLastFlush;
 
 public:
     void FlushIfHeavyGLCallsSinceLastFlush();
     static bool ShouldSpew();
-    static bool ShouldDumpExts();
 };
 
 bool DoesStringMatch(const char* aString, const char *aWantedString);
 
-void SplitByChar(const nsACString& str, const char delim,
-                 std::vector<nsACString*>* out);
-
-template<size_t N>
-bool
-MarkBitfieldByString(const nsACString& str, const char* (&markStrList)[N],
-                     std::bitset<N>& markList)
-{
-    for (size_t i = 0; i < N; i++) {
-        if (str.Equals(markStrList[i])) {
-            markList[i] = 1;
-            return true;
-        }
-    }
-    return false;
-}
-
-template<size_t N>
-void
-MarkBitfieldByStrings(const std::vector<nsACString*> strList,
-                      bool dumpStrings, const char* (&markStrList)[N],
-                      std::bitset<N>& markList)
-{
-    for (auto itr = strList.begin(); itr != strList.end(); ++itr) {
-        const nsACString& str = **itr;
-        const bool wasMarked = MarkBitfieldByString(str, markStrList,
-                                                    markList);
-        if (dumpStrings) {
-            nsCString nullTermed(str);
-            printf_stderr("  %s%s\n", nullTermed.BeginReading(),
-                          wasMarked ? "(*)" : "");
-        }
-    }
-}
-
-template<typename C>
-void
-DeleteAndClearIterable(C& cont)
-{
-    for(auto itr = cont.begin(); itr != cont.end(); ++itr) {
-        delete *itr;
-    }
-    cont.clear();
-}
 
 } /* namespace gl */
 } /* namespace mozilla */
 
 #endif /* GLCONTEXT_H_ */
--- a/gfx/gl/GLContextCGL.h
+++ b/gfx/gl/GLContextCGL.h
@@ -23,18 +23,20 @@ namespace gl {
 class GLContextCGL : public GLContext
 {
     friend class GLContextProviderCGL;
 
     NSOpenGLContext *mContext;
 
 public:
     MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(GLContextCGL, MOZ_OVERRIDE)
-    GLContextCGL(const SurfaceCaps& caps, NSOpenGLContext* context,
-                 bool isOffscreen, ContextProfile profile);
+    GLContextCGL(const SurfaceCaps& caps,
+                 GLContext *shareContext,
+                 NSOpenGLContext *context,
+                 bool isOffscreen = false);
 
     ~GLContextCGL();
 
     virtual GLContextType GetContextType() const MOZ_OVERRIDE { return GLContextType::CGL; }
 
     static GLContextCGL* Cast(GLContext* gl) {
         MOZ_ASSERT(gl->GetContextType() == GLContextType::CGL);
         return static_cast<GLContextCGL*>(gl);
--- a/gfx/gl/GLContextFeatures.cpp
+++ b/gfx/gl/GLContextFeatures.cpp
@@ -270,26 +270,16 @@ static const FeatureInfo sFeatureInfoArr
             GLContext::Extensions_End
         }
         /*
          * XXX_get_query_object_iv only provide GetQueryObjectiv provided by
          * ARB_occlusion_query (added by OpenGL 2.0).
          */
     },
     {
-        "get_string_indexed",
-        GLVersion::GL3,
-        GLESVersion::ES3,
-        GLContext::Extension_None,
-        {
-            GLContext::Extensions_End
-        }
-        // glGetStringi
-    },
-    {
         "gpu_shader4",
         GLVersion::GL3,
         GLESVersion::ES3,
         GLContext::Extension_None,
         {
             GLContext::EXT_gpu_shader4,
             GLContext::Extensions_End
         }
--- a/gfx/gl/GLContextProviderCGL.mm
+++ b/gfx/gl/GLContextProviderCGL.mm
@@ -16,66 +16,83 @@
 #include "GeckoProfiler.h"
 #include "mozilla/gfx/MacIOSurface.h"
 
 namespace mozilla {
 namespace gl {
 
 using namespace mozilla::gfx;
 
+static bool gUseDoubleBufferedWindows = true;
+
 class CGLLibrary
 {
 public:
     CGLLibrary()
-        : mInitialized(false)
-        , mUseDoubleBufferedWindows(true)
-        , mOGLLibrary(nullptr)
-    {}
+      : mInitialized(false),
+        mOGLLibrary(nullptr),
+        mPixelFormat(nullptr)
+    { }
 
     bool EnsureInitialized()
     {
         if (mInitialized) {
             return true;
         }
         if (!mOGLLibrary) {
             mOGLLibrary = PR_LoadLibrary("/System/Library/Frameworks/OpenGL.framework/OpenGL");
             if (!mOGLLibrary) {
                 NS_WARNING("Couldn't load OpenGL Framework.");
                 return false;
             }
         }
 
         const char* db = PR_GetEnv("MOZ_CGL_DB");
-        if (db) {
-            mUseDoubleBufferedWindows = *db != '0';
-        }
+        gUseDoubleBufferedWindows = (!db || *db != '0');
 
         mInitialized = true;
         return true;
     }
 
-    bool UseDoubleBufferedWindows() const {
-        MOZ_ASSERT(mInitialized);
-        return mUseDoubleBufferedWindows;
+    NSOpenGLPixelFormat *PixelFormat()
+    {
+        if (mPixelFormat == nullptr) {
+            NSOpenGLPixelFormatAttribute attribs[] = {
+                NSOpenGLPFAAccelerated,
+                NSOpenGLPFAAllowOfflineRenderers,
+                NSOpenGLPFADoubleBuffer,
+                0
+            };
+
+            if (!gUseDoubleBufferedWindows) {
+              attribs[2] = 0;
+            }
+
+            mPixelFormat = [[NSOpenGLPixelFormat alloc] initWithAttributes:attribs];
+        }
+
+        return mPixelFormat;
     }
-
 private:
     bool mInitialized;
-    bool mUseDoubleBufferedWindows;
     PRLibrary *mOGLLibrary;
+    NSOpenGLPixelFormat *mPixelFormat;
 };
 
 CGLLibrary sCGLLibrary;
 
-GLContextCGL::GLContextCGL(const SurfaceCaps& caps, NSOpenGLContext* context,
-                           bool isOffscreen, ContextProfile profile)
-    : GLContext(caps, nullptr, isOffscreen)
-    , mContext(context)
+GLContextCGL::GLContextCGL(
+                  const SurfaceCaps& caps,
+                  GLContext *shareContext,
+                  NSOpenGLContext *context,
+                  bool isOffscreen)
+    : GLContext(caps, shareContext, isOffscreen),
+      mContext(context)
 {
-    SetProfileVersion(profile, 210);
+    SetProfileVersion(ContextProfile::OpenGLCompatibility, 210);
 }
 
 GLContextCGL::~GLContextCGL()
 {
     MarkDestroyed();
 
     if (mContext) {
         if ([NSOpenGLContext currentContext] == mContext) {
@@ -140,17 +157,17 @@ bool
 GLContextCGL::SetupLookupFunction()
 {
     return false;
 }
 
 bool
 GLContextCGL::IsDoubleBuffered() const
 {
-  return sCGLLibrary.UseDoubleBufferedWindows();
+  return gUseDoubleBufferedWindows;
 }
 
 bool
 GLContextCGL::SupportsRobustness() const
 {
     return false;
 }
 
@@ -160,147 +177,99 @@ GLContextCGL::SwapBuffers()
   PROFILER_LABEL("GLContextCGL", "SwapBuffers",
     js::ProfileEntry::Category::GRAPHICS);
 
   [mContext flushBuffer];
   return true;
 }
 
 
+static GLContextCGL *
+GetGlobalContextCGL()
+{
+    return static_cast<GLContextCGL*>(GLContextProviderCGL::GetGlobalContext());
+}
+
 already_AddRefed<GLContext>
 GLContextProviderCGL::CreateWrappingExisting(void*, void*)
 {
     return nullptr;
 }
 
-static const NSOpenGLPixelFormatAttribute kAttribs_singleBuffered[] = {
-    NSOpenGLPFAAccelerated,
-    NSOpenGLPFAAllowOfflineRenderers,
-    0
-};
-
-static const NSOpenGLPixelFormatAttribute kAttribs_doubleBuffered[] = {
-    NSOpenGLPFAAccelerated,
-    NSOpenGLPFAAllowOfflineRenderers,
-    NSOpenGLPFADoubleBuffer,
-    0
-};
-
-static const NSOpenGLPixelFormatAttribute kAttribs_offscreen[] = {
-    NSOpenGLPFAPixelBuffer,
-    0
-};
-
-static const NSOpenGLPixelFormatAttribute kAttribs_offscreen_coreProfile[] = {
-    NSOpenGLPFAAccelerated,
-    NSOpenGLPFAOpenGLProfile, NSOpenGLProfileVersion3_2Core,
-    0
-};
-
-static NSOpenGLContext*
-CreateWithFormat(const NSOpenGLPixelFormatAttribute* attribs)
-{
-    NSOpenGLPixelFormat* format = [[NSOpenGLPixelFormat alloc]
-                                   initWithAttributes:attribs];
-    if (!format)
-        return nullptr;
-
-    NSOpenGLContext* context = [[NSOpenGLContext alloc] initWithFormat:format
-                                shareContext:nullptr];
-
-    [format release];
-
-    return context;
-}
-
 already_AddRefed<GLContext>
 GLContextProviderCGL::CreateForWindow(nsIWidget *aWidget)
 {
-    if (!sCGLLibrary.EnsureInitialized()) {
-        return nullptr;
-    }
+    GLContextCGL *shareContext = GetGlobalContextCGL();
 
-    const NSOpenGLPixelFormatAttribute* attribs;
-    if (sCGLLibrary.UseDoubleBufferedWindows()) {
-        attribs = kAttribs_doubleBuffered;
-    } else {
-        attribs = kAttribs_singleBuffered;
-    }
-    NSOpenGLContext* context = CreateWithFormat(attribs);
+    NSOpenGLContext *context = [[NSOpenGLContext alloc]
+                                initWithFormat:sCGLLibrary.PixelFormat()
+                                shareContext:(shareContext ? shareContext->mContext : NULL)];
     if (!context) {
         return nullptr;
     }
 
     // make the context transparent
     GLint opaque = 0;
     [context setValues:&opaque forParameter:NSOpenGLCPSurfaceOpacity];
 
     SurfaceCaps caps = SurfaceCaps::ForRGBA();
-    ContextProfile profile = ContextProfile::OpenGLCompatibility;
-    nsRefPtr<GLContextCGL> glContext = new GLContextCGL(caps, context, false,
-                                                        profile);
-
+    nsRefPtr<GLContextCGL> glContext = new GLContextCGL(caps,
+                                                        shareContext,
+                                                        context);
     if (!glContext->Init()) {
-        glContext = nullptr;
-        [context release];
         return nullptr;
     }
 
     return glContext.forget();
 }
 
 static already_AddRefed<GLContextCGL>
-CreateOffscreenFBOContext(bool requireCompatProfile)
+CreateOffscreenFBOContext(bool aShare = true)
 {
     if (!sCGLLibrary.EnsureInitialized()) {
         return nullptr;
     }
 
-    ContextProfile profile;
-    NSOpenGLContext* context = nullptr;
+    GLContextCGL *shareContext = aShare ? GetGlobalContextCGL() : nullptr;
+    if (aShare && !shareContext) {
+        // if there is no share context, then we can't use FBOs.
+        return nullptr;
+    }
 
-    if (!requireCompatProfile) {
-        profile = ContextProfile::OpenGLCore;
-        context = CreateWithFormat(kAttribs_offscreen_coreProfile);
-    }
-    if (!context) {
-        profile = ContextProfile::OpenGLCompatibility;
-        context = CreateWithFormat(kAttribs_offscreen);
-    }
+    NSOpenGLContext *context = [[NSOpenGLContext alloc]
+                                initWithFormat:sCGLLibrary.PixelFormat()
+                                shareContext:shareContext ? shareContext->GetNSOpenGLContext() : NULL];
     if (!context) {
         return nullptr;
     }
 
     SurfaceCaps dummyCaps = SurfaceCaps::Any();
-    nsRefPtr<GLContextCGL> glContext = new GLContextCGL(dummyCaps, context,
-                                                        true, profile);
+    nsRefPtr<GLContextCGL> glContext = new GLContextCGL(dummyCaps, shareContext, context, true);
 
     return glContext.forget();
 }
 
 already_AddRefed<GLContext>
-GLContextProviderCGL::CreateHeadless(bool requireCompatProfile)
+GLContextProviderCGL::CreateHeadless()
 {
-    nsRefPtr<GLContextCGL> gl;
-    gl = CreateOffscreenFBOContext(requireCompatProfile);
-    if (!gl)
+    nsRefPtr<GLContextCGL> glContext = CreateOffscreenFBOContext();
+    if (!glContext)
         return nullptr;
 
-    if (!gl->Init())
+    if (!glContext->Init())
         return nullptr;
 
-    return gl.forget();
+    return glContext.forget();
 }
 
 already_AddRefed<GLContext>
 GLContextProviderCGL::CreateOffscreen(const gfxIntSize& size,
-                                      const SurfaceCaps& caps,
-                                      bool requireCompatProfile)
+                                      const SurfaceCaps& caps)
 {
-    nsRefPtr<GLContext> glContext = CreateHeadless(requireCompatProfile);
+    nsRefPtr<GLContext> glContext = CreateHeadless();
     if (!glContext->InitOffscreen(ToIntSize(size), caps))
         return nullptr;
 
     return glContext.forget();
 }
 
 static nsRefPtr<GLContext> gGlobalContext;
 
@@ -325,13 +294,13 @@ GLContextProviderCGL::GetGlobalContext()
     }
 
     return gGlobalContext;
 }
 
 void
 GLContextProviderCGL::Shutdown()
 {
-    gGlobalContext = nullptr;
+  gGlobalContext = nullptr;
 }
 
 } /* namespace gl */
 } /* namespace mozilla */
--- a/gfx/gl/GLContextProviderEGL.cpp
+++ b/gfx/gl/GLContextProviderEGL.cpp
@@ -873,17 +873,17 @@ GLContextEGL::CreateEGLPixmapOffscreenCo
     }
 
     glContext->HoldSurface(thebesSurface);
 
     return glContext.forget();
 }
 
 already_AddRefed<GLContext>
-GLContextProviderEGL::CreateHeadless(bool)
+GLContextProviderEGL::CreateHeadless()
 {
     if (!sEGLLibrary.EnsureInitialized()) {
         return nullptr;
     }
 
     gfxIntSize dummySize = gfxIntSize(16, 16);
     nsRefPtr<GLContext> glContext;
     glContext = GLContextEGL::CreateEGLPBufferOffscreenContext(dummySize);
@@ -892,20 +892,19 @@ GLContextProviderEGL::CreateHeadless(boo
 
     return glContext.forget();
 }
 
 // Under EGL, 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,
-                                      bool requireCompatProfile)
+                                      const SurfaceCaps& caps)
 {
-    nsRefPtr<GLContext> glContext = CreateHeadless(requireCompatProfile);
+    nsRefPtr<GLContext> glContext = CreateHeadless();
     if (!glContext)
         return nullptr;
 
     if (!glContext->InitOffscreen(ToIntSize(size), caps))
         return nullptr;
 
     return glContext.forget();
 }
--- a/gfx/gl/GLContextProviderGLX.cpp
+++ b/gfx/gl/GLContextProviderGLX.cpp
@@ -1208,32 +1208,31 @@ DONE_CREATING_PIXMAP:
                                                   true,
                                                   xsurface);
     }
 
     return glContext.forget();
 }
 
 already_AddRefed<GLContext>
-GLContextProviderGLX::CreateHeadless(bool)
+GLContextProviderGLX::CreateHeadless()
 {
     gfxIntSize dummySize = gfxIntSize(16, 16);
     nsRefPtr<GLContext> glContext = CreateOffscreenPixmapContext(dummySize);
     if (!glContext)
         return nullptr;
 
     return glContext.forget();
 }
 
 already_AddRefed<GLContext>
 GLContextProviderGLX::CreateOffscreen(const gfxIntSize& size,
-                                      const SurfaceCaps& caps,
-                                      bool requireCompatProfile)
+                                      const SurfaceCaps& caps)
 {
-    nsRefPtr<GLContext> glContext = CreateHeadless(requireCompatProfile);
+    nsRefPtr<GLContext> glContext = CreateHeadless();
     if (!glContext)
         return nullptr;
 
     if (!glContext->InitOffscreen(ToIntSize(size), caps))
         return nullptr;
 
     return glContext.forget();
 }
--- a/gfx/gl/GLContextProviderImpl.h
+++ b/gfx/gl/GLContextProviderImpl.h
@@ -53,22 +53,21 @@ public:
      *
      * @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,
-                    bool requireCompatProfile);
+                    const SurfaceCaps& caps);
 
     // Just create a context. We'll add offscreen stuff ourselves.
     static already_AddRefed<GLContext>
-    CreateHeadless(bool requireCompatProfile);
+    CreateHeadless();
 
     /**
      * Create wrapping Gecko GLContext for external gl context.
      *
      * @param aContext External context which will be wrapped by Gecko GLContext.
      * @param aSurface External surface which is used for external context.
      *
      * @return Wrapping Context to use for rendering
--- a/gfx/gl/GLContextProviderNull.cpp
+++ b/gfx/gl/GLContextProviderNull.cpp
@@ -17,24 +17,23 @@ GLContextProviderNull::CreateForWindow(n
 already_AddRefed<GLContext>
 GLContextProviderNull::CreateWrappingExisting(void*, void*)
 {
     return nullptr;
 }
 
 already_AddRefed<GLContext>
 GLContextProviderNull::CreateOffscreen(const gfxIntSize&,
-                                       const SurfaceCaps&,
-                                       bool)
+                                       const SurfaceCaps&)
 {
     return nullptr;
 }
 
 already_AddRefed<GLContext>
-GLContextProviderNull::CreateHeadless(bool)
+GLContextProviderNull::CreateHeadless()
 {
     return nullptr;
 }
 
 GLContext*
 GLContextProviderNull::GetGlobalContext(ContextFlags)
 {
     return nullptr;
--- a/gfx/gl/GLContextProviderWGL.cpp
+++ b/gfx/gl/GLContextProviderWGL.cpp
@@ -602,17 +602,17 @@ CreateWindowOffscreenContext()
     nsRefPtr<GLContextWGL> glContext = new GLContextWGL(caps,
                                                         shareContext, true,
                                                         dc, context, win);
 
     return glContext.forget();
 }
 
 already_AddRefed<GLContext>
-GLContextProviderWGL::CreateHeadless(bool)
+GLContextProviderWGL::CreateHeadless()
 {
     if (!sWGLLib.EnsureInitialized()) {
         return nullptr;
     }
 
     nsRefPtr<GLContextWGL> glContext;
 
     // Always try to create a pbuffer context first, because we
@@ -636,20 +636,19 @@ GLContextProviderWGL::CreateHeadless(boo
     }
 
     nsRefPtr<GLContext> retGL = glContext.get();
     return retGL.forget();
 }
 
 already_AddRefed<GLContext>
 GLContextProviderWGL::CreateOffscreen(const gfxIntSize& size,
-                                      const SurfaceCaps& caps,
-                                      bool requireCompatProfile)
+                                      const SurfaceCaps& caps)
 {
-    nsRefPtr<GLContext> glContext = CreateHeadless(requireCompatProfile);
+    nsRefPtr<GLContext> glContext = CreateHeadless();
     if (!glContext)
         return nullptr;
 
     if (!glContext->InitOffscreen(ToIntSize(size), caps))
         return nullptr;
 
     return glContext.forget();
 }
--- a/gfx/gl/GLContextSymbols.h
+++ b/gfx/gl/GLContextSymbols.h
@@ -661,18 +661,14 @@ struct GLContextSymbols
                                                            GLsizei width, GLsizei height, GLsizei depth,
                                                            GLint border, GLsizei imageSize, const GLvoid* data);
     PFNGLCOMPRESSEDTEXIMAGE3D fCompressedTexImage3D;
     typedef void (GLAPIENTRY * PFNGLCOMPRESSEDTEXSUBIMAGE3D) (GLenum target, GLint level,
                                                               GLint xoffset, GLint yoffset, GLint zoffset,
                                                               GLsizei width, GLsizei height, GLsizei depth,
                                                               GLenum format, GLsizei imageSize, const GLvoid* data);
     PFNGLCOMPRESSEDTEXSUBIMAGE3D fCompressedTexSubImage3D;
-
-    // get_string_indexed
-    typedef const GLubyte* (GLAPIENTRY * pfnGLGetStringiT)(GLenum name, GLuint index);
-    pfnGLGetStringiT fGetStringi;
 };
 
 }
 }
 
 #endif /* GLCONTEXTSYMBOLS_H_ */
--- a/gfx/gl/GLContextTypes.cpp
+++ b/gfx/gl/GLContextTypes.cpp
@@ -7,8 +7,13 @@
 #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
@@ -38,12 +38,25 @@ struct GLFormats
 
     GLenum depthStencil;
     GLenum depth;
     GLenum stencil;
 
     GLsizei samples;
 };
 
+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_ */
--- a/gfx/gl/GLLibraryEGL.cpp
+++ b/gfx/gl/GLLibraryEGL.cpp
@@ -30,17 +30,18 @@ static const char *sEGLExtensionNames[] 
     "EGL_KHR_image_base",
     "EGL_KHR_image_pixmap",
     "EGL_KHR_gl_texture_2D_image",
     "EGL_KHR_lock_surface",
     "EGL_ANGLE_surface_d3d_texture_2d_share_handle",
     "EGL_EXT_create_context_robustness",
     "EGL_KHR_image",
     "EGL_KHR_fence_sync",
-    "EGL_ANDROID_native_fence_sync"
+    "EGL_ANDROID_native_fence_sync",
+    nullptr
 };
 
 #if defined(ANDROID)
 
 static PRLibrary* LoadApitraceLibrary()
 {
     if (!gfxPrefs::UseApitrace()) {
         return nullptr;
@@ -415,33 +416,25 @@ GLLibraryEGL::EnsureInitialized()
     mInitialized = true;
     reporter.SetSuccessful();
     return true;
 }
 
 void
 GLLibraryEGL::InitExtensions()
 {
-    const char* rawExts = (const char*)fQueryString(mEGLDisplay,
-                                                    LOCAL_EGL_EXTENSIONS);
-    if (rawExts) {
-        nsDependentCString exts(rawExts);
-        SplitByChar(exts, ' ', &mDriverExtensionList);
-    } else {
+    const char *extensions = (const char*)fQueryString(mEGLDisplay, LOCAL_EGL_EXTENSIONS);
+
+    if (!extensions) {
         NS_WARNING("Failed to load EGL extension list!");
+        return;
     }
 
-    const bool shouldDumpExts = GLContext::ShouldDumpExts();
-    if (shouldDumpExts) {
-        printf_stderr("%i EGL driver extensions:\n",
-                      (uint32_t)mDriverExtensionList.size());
-    }
-
-    MarkBitfieldByStrings(mDriverExtensionList, shouldDumpExts,
-                          sEGLExtensionNames, mAvailableExtensions);
+    GLContext::InitializeExtensionsBitSet(mAvailableExtensions, extensions,
+                                          sEGLExtensionNames);
 }
 
 void
 GLLibraryEGL::DumpEGLConfig(EGLConfig cfg)
 {
     int attrval;
     int err;
 
--- a/gfx/gl/GLLibraryEGL.h
+++ b/gfx/gl/GLLibraryEGL.h
@@ -10,17 +10,16 @@
 #endif
 
 #include "GLLibraryLoader.h"
 #include "mozilla/ThreadLocal.h"
 #include "nsIFile.h"
 #include "GeckoProfiler.h"
 
 #include <bitset>
-#include <vector>
 
 #if defined(XP_WIN)
 
 #ifndef WIN32_LEAN_AND_MEAN
 #define WIN32_LEAN_AND_MEAN 1
 #endif
 
 #include <windows.h>
@@ -138,17 +137,16 @@ public:
         return mAvailableExtensions[aKnownExtension];
     }
 
     void MarkExtensionUnsupported(EGLExtensions aKnownExtension) {
         mAvailableExtensions[aKnownExtension] = false;
     }
 
 protected:
-    std::vector<nsACString*> mDriverExtensionList;
     std::bitset<Extensions_Max> mAvailableExtensions;
 
 public:
 
     EGLDisplay fGetDisplay(void* display_id)
     {
         BEFORE_GL_CALL;
         EGLDisplay disp = mSymbols.fGetDisplay(display_id);
--- a/gfx/layers/GLImages.cpp
+++ b/gfx/layers/GLImages.cpp
@@ -34,17 +34,17 @@ EGLImageImage::~EGLImageImage()
 }
 
 TemporaryRef<gfx::SourceSurface>
 GLImage::GetAsSourceSurface()
 {
   MOZ_ASSERT(NS_IsMainThread(), "Should be on the main thread");
 
   if (!sSnapshotContext) {
-    sSnapshotContext = GLContextProvider::CreateHeadless(false);
+    sSnapshotContext = GLContextProvider::CreateHeadless();
     if (!sSnapshotContext) {
       NS_WARNING("Failed to create snapshot GLContext");
       return nullptr;
     }
   }
 
   sSnapshotContext->MakeCurrent();
   ScopedTexture scopedTex(sSnapshotContext);
--- a/gfx/layers/opengl/CompositorOGL.cpp
+++ b/gfx/layers/opengl/CompositorOGL.cpp
@@ -119,21 +119,18 @@ CompositorOGL::CreateContext()
   }
 #endif
 
   // Allow to create offscreen GL context for main Layer Manager
   if (!context && PR_GetEnv("MOZ_LAYERS_PREFER_OFFSCREEN")) {
     SurfaceCaps caps = SurfaceCaps::ForRGB();
     caps.preserve = false;
     caps.bpp16 = gfxPlatform::GetPlatform()->GetOffscreenFormat() == gfxImageFormat::RGB16_565;
-
-    bool requireCompatProfile = true;
     context = GLContextProvider::CreateOffscreen(gfxIntSize(mSurfaceSize.width,
-                                                            mSurfaceSize.height),
-                                                 caps, requireCompatProfile);
+                                                            mSurfaceSize.height), caps);
   }
 
   if (!context)
     context = gl::GLContextProvider::CreateForWindow(mWidget);
 
   if (!context) {
     NS_WARNING("Failed to create CompositorOGL context");
   }
--- a/gfx/tests/gtest/TestCompositor.cpp
+++ b/gfx/tests/gtest/TestCompositor.cpp
@@ -40,17 +40,17 @@ public:
   NS_IMETHOD              GetBounds(nsIntRect &aRect) MOZ_OVERRIDE { return GetClientBounds(aRect); }
 
   void* GetNativeData(uint32_t aDataType) MOZ_OVERRIDE {
     if (aDataType == NS_NATIVE_OPENGL_CONTEXT) {
       mozilla::gl::SurfaceCaps caps = mozilla::gl::SurfaceCaps::ForRGB();
       caps.preserve = false;
       caps.bpp16 = false;
       nsRefPtr<GLContext> context = GLContextProvider::CreateOffscreen(
-        gfxIntSize(gCompWidth, gCompHeight), caps, true);
+        gfxIntSize(gCompWidth, gCompHeight), caps);
       return context.forget().take();
     }
     return nullptr;
   }
 
   NS_IMETHOD              Create(nsIWidget *aParent,
                                  nsNativeWidget aNativeParent,
                                  const nsIntRect &aRect,
--- a/gfx/thebes/gfxPlatform.cpp
+++ b/gfx/thebes/gfxPlatform.cpp
@@ -1094,19 +1094,18 @@ gfxPlatform::GetSkiaGLGlue()
 {
 #ifdef USE_SKIA_GPU
   if (!mSkiaGlue) {
     /* Dummy context. We always draw into a FBO.
      *
      * FIXME: This should be stored in TLS or something, since there needs to be one for each thread using it. As it
      * stands, this only works on the main thread.
      */
-    bool requireCompatProfile = true;
-    nsRefPtr<mozilla::gl::GLContext> glContext;
-    glContext = mozilla::gl::GLContextProvider::CreateHeadless(requireCompatProfile);
+    mozilla::gl::SurfaceCaps caps = mozilla::gl::SurfaceCaps::ForRGBA();
+    nsRefPtr<mozilla::gl::GLContext> glContext = mozilla::gl::GLContextProvider::CreateOffscreen(gfxIntSize(16, 16), caps);
     if (!glContext) {
       printf_stderr("Failed to create GLContext for SkiaGL!\n");
       return nullptr;
     }
     mSkiaGlue = new mozilla::gl::SkiaGLGlue(glContext);
     MOZ_ASSERT(mSkiaGlue->GetGrContext(), "No GrContext");
     InitializeSkiaCacheLimits();
   }
--- a/widget/android/GfxInfo.cpp
+++ b/widget/android/GfxInfo.cpp
@@ -67,18 +67,18 @@ public:
   }
 
   void EnsureInitialized() {
     if (mReady) {
       return;
     }
 
     nsRefPtr<gl::GLContext> gl;
-    bool requireCompatProfile = true;
-    gl = gl::GLContextProvider::CreateHeadless(requireCompatProfile);
+    gl = gl::GLContextProvider::CreateOffscreen(gfxIntSize(16, 16),
+                                                gl::SurfaceCaps::ForRGB());
 
     if (!gl) {
       // Setting mReady to true here means that we won't retry. Everything will
       // remain blacklisted forever. Ideally, we would like to update that once
       // any GLContext is successfully created, like the compositor's GLContext.
       mReady = true;
       return;
     }