Backed out changeset 6bcda9f223b3 (bug 996266) for bustage on a CLOSED TREE
authorCarsten "Tomcat" Book <cbook@mozilla.com>
Wed, 27 Aug 2014 11:15:40 +0200
changeset 223576 00db70d58a1aa8a2d46dd4148a1f75149b3766f0
parent 223575 365cdbcaaf6a582778c6e800d1e0fbd1ba320279
child 223577 437f9ad3fec974b73e727bba3a40663274466856
push id3979
push userraliiev@mozilla.com
push dateMon, 13 Oct 2014 16:35:44 +0000
treeherdermozilla-beta@30f2cc610691 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
bugs996266
milestone34.0a1
backs out6bcda9f223b3e832c374c67f43168e863eeafc30
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 6bcda9f223b3 (bug 996266) for bustage on a CLOSED TREE
dom/canvas/WebGLContext.cpp
dom/canvas/WebGLContext.h
dom/canvas/test/reftest/reftest.list
gfx/gl/GLContext.cpp
gfx/gl/GLContext.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/SurfaceTypes.cpp
modules/libpref/init/all.js
--- a/dom/canvas/WebGLContext.cpp
+++ b/dom/canvas/WebGLContext.cpp
@@ -67,18 +67,16 @@
 #include "mozilla/EnumeratedArrayCycleCollection.h"
 
 #include "Layers.h"
 
 #ifdef MOZ_WIDGET_GONK
 #include "mozilla/layers/ShadowLayers.h"
 #endif
 
-#include <queue>
-
 using namespace mozilla;
 using namespace mozilla::dom;
 using namespace mozilla::gfx;
 using namespace mozilla::gl;
 using namespace mozilla::layers;
 
 WebGLObserver::WebGLObserver(WebGLContext* aContext)
     : mContext(aContext)
@@ -432,20 +430,22 @@ WebGLContext::SetContextOptions(JSContex
 
     WebGLContextOptions newOpts;
 
     newOpts.stencil = attributes.mStencil;
     newOpts.depth = attributes.mDepth;
     newOpts.premultipliedAlpha = attributes.mPremultipliedAlpha;
     newOpts.antialias = attributes.mAntialias;
     newOpts.preserveDrawingBuffer = attributes.mPreserveDrawingBuffer;
+    if (attributes.mAlpha.WasPassed()) {
+      newOpts.alpha = attributes.mAlpha.Value();
+    }
 
-    if (attributes.mAlpha.WasPassed()) {
-        newOpts.alpha = attributes.mAlpha.Value();
-    }
+    // enforce that if stencil is specified, we also give back depth
+    newOpts.depth |= newOpts.stencil;
 
     // Don't do antialiasing if we've disabled MSAA.
     if (!gfxPrefs::MSAALevel()) {
       newOpts.antialias = false;
     }
 
 #if 0
     GenerateWarning("aaHint: %d stencil: %d depth: %d alpha: %d premult: %d preserve: %d\n",
@@ -466,467 +466,266 @@ WebGLContext::SetContextOptions(JSContex
     mOptions = newOpts;
     return NS_OK;
 }
 
 #ifdef DEBUG
 int32_t
 WebGLContext::GetWidth() const
 {
-    return mWidth;
+  return mWidth;
 }
 
 int32_t
 WebGLContext::GetHeight() const
 {
-    return mHeight;
+  return mHeight;
 }
 #endif
 
-/* So there are a number of points of failure here. We might fail based
- * on EGL vs. WGL, or we might fail to alloc a too-large size, or we
- * might not be able to create a context with a certain combo of context
- * creation attribs.
- *
- * We don't want to test the complete fallback matrix. (for now, at
- * least) Instead, attempt creation in this order:
- * 1. By platform API. (e.g. EGL vs. WGL)
- * 2. By context creation attribs.
- * 3. By size.
- *
- * That is, try to create headless contexts based on the platform API.
- * Next, create dummy-sized backbuffers for the contexts with the right
- * caps. Finally, resize the backbuffer to an acceptable size given the
- * requested size.
- */
-
-static bool
-IsFeatureInBlacklist(const nsCOMPtr<nsIGfxInfo>& gfxInfo, int32_t feature)
-{
-    int32_t status;
-    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,
-                       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();
-    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,
-                    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();
-    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,
-                  const nsCOMPtr<nsIGfxInfo>& gfxInfo,
-                  WebGLContext* webgl)
-{
-    nsRefPtr<GLContext> gl;
-
-#ifdef ANDROID
-    gl = gl::GLContextProviderEGL::CreateHeadless();
-    if (!gl) {
-        webgl->GenerateWarning("Error during EGL OpenGL init.");
-        return nullptr;
-    }
-    MOZ_ASSERT(!gl->IsANGLE());
-#endif
-
-    return gl.forget();
-}
-
-
-static already_AddRefed<GLContext>
-CreateHeadlessGL(bool forceEnabled,
-                 const nsCOMPtr<nsIGfxInfo>& gfxInfo,
-                 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;
-    }
-
-    nsRefPtr<GLContext> gl;
-
-    if (preferEGL)
-        gl = CreateHeadlessEGL(forceEnabled, gfxInfo, webgl);
-
-    if (!gl && !disableANGLE)
-        gl = CreateHeadlessANGLE(forceEnabled, gfxInfo, 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)
-{
-    gfx::IntSize dummySize(16, 16);
-    return gl->InitOffscreen(dummySize, caps);
-}
-
-static void
-PopulateCapFallbackQueue(const SurfaceCaps& baseCaps,
-                         std::queue<SurfaceCaps>* fallbackCaps)
-{
-    fallbackCaps->push(baseCaps);
-
-    // Dropping antialias drops our quality, but not our correctness.
-    // The user basically doesn't have to handle if this fails, they
-    // just get reduced quality.
-    if (baseCaps.antialias) {
-        SurfaceCaps nextCaps(baseCaps);
-        nextCaps.antialias = false;
-        PopulateCapFallbackQueue(nextCaps, fallbackCaps);
-    }
-
-    // If we have to drop one of depth or stencil, we'd prefer to keep
-    // depth. However, the client app will need to handle if this
-    // doesn't work.
-    if (baseCaps.stencil) {
-        SurfaceCaps nextCaps(baseCaps);
-        nextCaps.stencil = false;
-        PopulateCapFallbackQueue(nextCaps, fallbackCaps);
-    }
-
-    if (baseCaps.depth) {
-        SurfaceCaps nextCaps(baseCaps);
-        nextCaps.depth = false;
-        PopulateCapFallbackQueue(nextCaps, fallbackCaps);
-    }
-}
-
-static bool
-CreateOffscreen(GLContext* gl,
-                const WebGLContextOptions& options,
-                const nsCOMPtr<nsIGfxInfo>& gfxInfo,
-                WebGLContext* webgl,
-                layers::ISurfaceAllocator* surfAllocator)
-{
-    SurfaceCaps baseCaps;
-
-    baseCaps.color = true;
-    baseCaps.alpha = options.alpha;
-    baseCaps.antialias = options.antialias;
-    baseCaps.depth = options.depth;
-    baseCaps.preserve = options.preserveDrawingBuffer;
-    baseCaps.stencil = options.stencil;
-
-    // we should really have this behind a
-    // |gfxPlatform::GetPlatform()->GetScreenDepth() == 16| check, but
-    // for now it's just behind a pref for testing/evaluation.
-    baseCaps.bpp16 = Preferences::GetBool("webgl.prefer-16bpp", false);
-
-#ifdef MOZ_WIDGET_GONK
-    baseCaps.surfaceAllocator = surfAllocator;
-#endif
-
-    // Done with baseCaps construction.
-
-    bool forceAllowAA = Preferences::GetBool("webgl.msaa-force", false);
-    if (!forceAllowAA &&
-        IsFeatureInBlacklist(gfxInfo, nsIGfxInfo::FEATURE_WEBGL_MSAA))
-    {
-        webgl->GenerateWarning("Disallowing antialiased backbuffers due"
-                               " to blacklisting.");
-        baseCaps.antialias = false;
-    }
-
-    std::queue<SurfaceCaps> fallbackCaps;
-    PopulateCapFallbackQueue(baseCaps, &fallbackCaps);
-
-    bool created = false;
-    while (!fallbackCaps.empty()) {
-        SurfaceCaps& caps = fallbackCaps.front();
-
-        created = CreateOffscreenWithCaps(gl, caps);
-        if (created)
-            break;
-
-        fallbackCaps.pop();
-    }
-
-    return created;
-}
-
-bool
-WebGLContext::CreateOffscreenGL(bool forceEnabled)
-{
-    nsCOMPtr<nsIGfxInfo> gfxInfo = do_GetService("@mozilla.org/gfx/info;1");
-
-    layers::ISurfaceAllocator* surfAllocator = nullptr;
-#ifdef MOZ_WIDGET_GONK
-    nsIWidget* docWidget = nsContentUtils::WidgetForDocument(mCanvasElement->OwnerDoc());
-    if (docWidget) {
-        layers::LayerManager* layerManager = docWidget->GetLayerManager();
-        if (layerManager) {
-            // XXX we really want "AsSurfaceAllocator" here for generality
-            layers::ShadowLayerForwarder* forwarder = layerManager->AsShadowForwarder();
-            if (forwarder) {
-                surfAllocator = static_cast<layers::ISurfaceAllocator*>(forwarder);
-            }
-        }
-    }
-#endif
-
-    gl = CreateHeadlessGL(forceEnabled, gfxInfo, this);
-
-    do {
-        if (!gl)
-            break;
-
-        if (!CreateOffscreen(gl, mOptions, gfxInfo, this, surfAllocator))
-            break;
-
-        if (!InitAndValidateGL())
-            break;
-
-        return true;
-    } while (false);
-
-    gl = nullptr;
-    return false;
-}
-
-// Fallback for resizes:
-bool
-WebGLContext::ResizeBackbuffer(uint32_t requestedWidth, uint32_t requestedHeight)
-{
-    uint32_t width = requestedWidth;
-    uint32_t height = requestedHeight;
-
-    bool resized = false;
-    while (width || height) {
-      width = width ? width : 1;
-      height = height ? height : 1;
-
-      gfx::IntSize curSize(width, height);
-      if (gl->ResizeOffscreen(curSize)) {
-          resized = true;
-          break;
-      }
-
-      width /= 2;
-      height /= 2;
-    }
-
-    if (!resized)
-        return false;
-
-    mWidth = gl->OffscreenSize().width;
-    mHeight = gl->OffscreenSize().height;
-    MOZ_ASSERT((uint32_t)mWidth == width);
-    MOZ_ASSERT((uint32_t)mHeight == height);
-
-    if (width != requestedWidth ||
-        height != requestedHeight)
-    {
-        GenerateWarning("Requested size %dx%d was too large, but resize"
-                          " to %dx%d succeeded.",
-                        requestedWidth, requestedHeight,
-                        width, height);
-    }
-    return true;
-}
-
-
 NS_IMETHODIMP
-WebGLContext::SetDimensions(int32_t sWidth, int32_t sHeight)
+WebGLContext::SetDimensions(int32_t width, int32_t height)
 {
     // Early error return cases
-    if (!GetCanvas())
-        return NS_ERROR_FAILURE;
 
-    if (sWidth < 0 || sHeight < 0) {
+    if (width < 0 || height < 0) {
         GenerateWarning("Canvas size is too large (seems like a negative value wrapped)");
         return NS_ERROR_OUT_OF_MEMORY;
     }
 
-    uint32_t width = sWidth;
-    uint32_t height = sHeight;
+    if (!GetCanvas())
+        return NS_ERROR_FAILURE;
 
     // Early success return cases
+
     GetCanvas()->InvalidateCanvas();
 
+    if (gl && mWidth == width && mHeight == height)
+        return NS_OK;
+
     // Zero-sized surfaces can cause problems.
     if (width == 0) {
         width = 1;
     }
     if (height == 0) {
         height = 1;
     }
 
     // If we already have a gl context, then we just need to resize it
     if (gl) {
-        if ((uint32_t)mWidth == width &&
-            (uint32_t)mHeight == height)
-        {
-            return NS_OK;
-        }
-
-        if (IsContextLost())
-            return NS_OK;
-
         MakeContextCurrent();
 
         // If we've already drawn, we should commit the current buffer.
         PresentScreenBuffer();
 
         // ResizeOffscreen scraps the current prod buffer before making a new one.
-        if (!ResizeBackbuffer(width, height)) {
-            GenerateWarning("WebGL context failed to resize.");
-            ForceLoseContext();
-            return NS_OK;
-        }
+        gl->ResizeOffscreen(gfx::IntSize(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;
         mResetLayer = true;
+
         mBackbufferNeedsClear = 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.
 
     // if we exceeded either the global or the per-principal limit for WebGL contexts,
     // lose the oldest-used context now to free resources. Note that we can't do that
     // in the WebGLContext constructor as we don't have a canvas element yet there.
     // Here is the right place to do so, as we are about to create the OpenGL context
     // and that is what can fail if we already have too many.
     LoseOldestWebGLContextIfLimitExceeded();
 
+    // Get some prefs for some preferred/overriden things
+    NS_ENSURE_TRUE(Preferences::GetRootBranch(), NS_ERROR_FAILURE);
+
+#ifdef XP_WIN
+    bool preferEGL =
+        Preferences::GetBool("webgl.prefer-egl", false);
+    bool preferOpenGL =
+        Preferences::GetBool("webgl.prefer-native-gl", false);
+#endif
+    bool forceEnabled =
+        Preferences::GetBool("webgl.force-enabled", false);
+    bool disabled =
+        Preferences::GetBool("webgl.disabled", false);
+    bool prefer16bit =
+        Preferences::GetBool("webgl.prefer-16bpp", false);
+
+    ScopedGfxFeatureReporter reporter("WebGL", forceEnabled);
+
+    if (disabled)
+        return NS_ERROR_FAILURE;
+
     // We're going to create an entirely new context.  If our
     // generation is not 0 right now (that is, if this isn't the first
     // context we're creating), we may have to dispatch a context lost
     // 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()) {
-        GenerateWarning("Too many WebGL contexts created this run.");
+    if (!(mGeneration + 1).isValid())
         return NS_ERROR_FAILURE; // exit without changing the value of mGeneration
+
+    SurfaceCaps caps;
+
+    caps.color = true;
+    caps.alpha = mOptions.alpha;
+    caps.depth = mOptions.depth;
+    caps.stencil = mOptions.stencil;
+
+    // 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;
+
+#ifdef MOZ_WIDGET_GONK
+    nsIWidget *docWidget = nsContentUtils::WidgetForDocument(mCanvasElement->OwnerDoc());
+    if (docWidget) {
+        layers::LayerManager *layerManager = docWidget->GetLayerManager();
+        if (layerManager) {
+            // XXX we really want "AsSurfaceAllocator" here for generality
+            layers::ShadowLayerForwarder *forwarder = layerManager->AsShadowForwarder();
+            if (forwarder) {
+                caps.surfaceAllocator = static_cast<layers::ISurfaceAllocator*>(forwarder);
+            }
+        }
+    }
+#endif
+
+    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_STATUS_OK || forceMSAA) {
+            caps.antialias = true;
+        }
     }
 
-    // Get some prefs for some preferred/overriden things
-    NS_ENSURE_TRUE(Preferences::GetRootBranch(), NS_ERROR_FAILURE);
+#ifdef XP_WIN
+    if (PR_GetEnv("MOZ_WEBGL_PREFER_EGL")) {
+        preferEGL = true;
+    }
+#endif
+
+    // Ask GfxInfo about what we should use
+    bool useOpenGL = true;
+
+#ifdef XP_WIN
+    bool useANGLE = true;
+#endif
 
-    bool disabled = Preferences::GetBool("webgl.disabled", false);
-    if (disabled) {
-        GenerateWarning("WebGL creation is disabled, and so disallowed here.");
-        return NS_ERROR_FAILURE;
+    if (gfxInfo && !forceEnabled) {
+        if (NS_SUCCEEDED(gfxInfo->GetFeatureStatus(nsIGfxInfo::FEATURE_WEBGL_OPENGL, &status))) {
+            if (status != nsIGfxInfo::FEATURE_STATUS_OK) {
+                useOpenGL = false;
+            }
+        }
+#ifdef XP_WIN
+        if (NS_SUCCEEDED(gfxInfo->GetFeatureStatus(nsIGfxInfo::FEATURE_WEBGL_ANGLE, &status))) {
+            if (status != nsIGfxInfo::FEATURE_STATUS_OK) {
+                useANGLE = false;
+            }
+        }
+#endif
     }
 
-    // Alright, now let's start trying.
-    bool forceEnabled = Preferences::GetBool("webgl.force-enabled", false);
-    ScopedGfxFeatureReporter reporter("WebGL", forceEnabled);
+#ifdef XP_WIN
+    // allow forcing GL and not EGL/ANGLE
+    if (PR_GetEnv("MOZ_WEBGL_FORCE_OPENGL")) {
+        preferEGL = false;
+        useANGLE = false;
+        useOpenGL = true;
+    }
+#endif
+
+    gfxIntSize size(width, height);
 
-    if (!CreateOffscreenGL(forceEnabled)) {
-        GenerateWarning("WebGL creation failed.");
-        return NS_ERROR_FAILURE;
+#ifdef XP_WIN
+    // if we want EGL, try it now
+    if (!gl && (preferEGL || useANGLE) && !preferOpenGL) {
+        gl = gl::GLContextProviderEGL::CreateOffscreen(size, caps);
+        if (!gl || !InitAndValidateGL()) {
+            GenerateWarning("Error during ANGLE OpenGL ES initialization");
+            return NS_ERROR_FAILURE;
+        }
     }
-    MOZ_ASSERT(gl);
+#endif
 
-    if (!ResizeBackbuffer(width, height)) {
-        GenerateWarning("Initializing WebGL backbuffer failed.");
+    // try the default provider, whatever that is
+    if (!gl && useOpenGL) {
+        gl = gl::GLContextProvider::CreateOffscreen(size, caps);
+        if (gl && !InitAndValidateGL()) {
+            GenerateWarning("Error during OpenGL initialization");
+            return NS_ERROR_FAILURE;
+        }
+    }
+
+    if (!gl) {
+        GenerateWarning("Can't get a usable WebGL context");
         return NS_ERROR_FAILURE;
     }
 
 #ifdef DEBUG
     if (gl->DebugMode()) {
         printf_stderr("--- WebGL context created: %p\n", gl.get());
     }
 #endif
 
+    mWidth = width;
+    mHeight = height;
+    mViewportWidth = width;
+    mViewportHeight = height;
     mResetLayer = true;
     mOptionsFrozen = true;
 
     // increment the generation number
     ++mGeneration;
+#if 0
+    if (mGeneration > 0) {
+        // XXX dispatch context lost event
+    }
+#endif
 
     MakeContextCurrent();
 
-    gl->fViewport(0, 0, mWidth, mHeight);
-    mViewportWidth = mWidth;
-    mViewportHeight = mHeight;
-
     // Make sure that we clear this out, otherwise
     // we'll end up displaying random memory
     gl->fBindFramebuffer(LOCAL_GL_FRAMEBUFFER, 0);
 
     AssertCachedBindings();
     AssertCachedState();
 
     // Clear immediately, because we need to present the cleared initial
     // buffer.
     mBackbufferNeedsClear = true;
     ClearBackbufferIfNeeded();
 
     mShouldPresent = true;
 
-    MOZ_ASSERT(gl->Caps().color);
-    MOZ_ASSERT(gl->Caps().alpha == mOptions.alpha);
-    MOZ_ASSERT(gl->Caps().depth == mOptions.depth || !gl->Caps().depth);
-    MOZ_ASSERT(gl->Caps().stencil == mOptions.stencil || !gl->Caps().stencil);
-    MOZ_ASSERT(gl->Caps().antialias == mOptions.antialias || !gl->Caps().antialias);
-    MOZ_ASSERT(gl->Caps().preserve == mOptions.preserveDrawingBuffer);
+    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);
 
     AssertCachedBindings();
     AssertCachedState();
 
     reporter.SetSuccessful();
     return NS_OK;
 }
 
@@ -1407,17 +1206,17 @@ WebGLContext::PresentScreenBuffer()
 
     if (!mShouldPresent) {
         return false;
     }
 
     gl->MakeCurrent();
     MOZ_ASSERT(!mBackbufferNeedsClear);
     if (!gl->PublishFrame()) {
-        ForceLoseContext();
+        this->ForceLoseContext();
         return false;
     }
 
     if (!mOptions.preserveDrawingBuffer) {
         mBackbufferNeedsClear = true;
     }
 
     mShouldPresent = false;
--- a/dom/canvas/WebGLContext.h
+++ b/dom/canvas/WebGLContext.h
@@ -1031,19 +1031,17 @@ protected:
 
     bool InitWebGL2();
 
 
     // -------------------------------------------------------------------------
     // Validation functions (implemented in WebGLContextValidate.cpp)
     GLenum BaseTexFormat(GLenum internalFormat) const;
 
-    bool CreateOffscreenGL(bool forceEnabled);
     bool InitAndValidateGL();
-    bool ResizeBackbuffer(uint32_t width, uint32_t height);
     bool ValidateBlendEquationEnum(GLenum cap, const char *info);
     bool ValidateBlendFuncDstEnum(GLenum mode, const char *info);
     bool ValidateBlendFuncSrcEnum(GLenum mode, const char *info);
     bool ValidateBlendFuncEnumsCompatibility(GLenum sfactor, GLenum dfactor, const char *info);
     bool ValidateTextureTargetEnum(GLenum target, const char *info);
     bool ValidateComparisonEnum(GLenum target, const char *info);
     bool ValidateStencilOpEnum(GLenum action, const char *info);
     bool ValidateFaceEnum(GLenum face, const char *info);
--- a/dom/canvas/test/reftest/reftest.list
+++ b/dom/canvas/test/reftest/reftest.list
@@ -170,20 +170,20 @@ pref(webgl.force-layers-readback,true) r
 
 # Check that our experimental prefs still work:
 
 # 16bpp:
 skip-if(winWidget) pref(webgl.prefer-16bpp,true)                                        random-if(Android&&AndroidVersion<15)  == webgl-color-test.html?16bpp           wrapper.html?colors.png
 skip-if(winWidget) pref(webgl.prefer-16bpp,true) pref(webgl.force-layers-readback,true) random-if(Android&&AndroidVersion<15)  == webgl-color-test.html?16bpp&readback  wrapper.html?colors.png
 
 # Force native GL (Windows):
-skip-if(!winWidget) pref(webgl.disable-angle,true)                                == webgl-clear-test.html?native-gl        wrapper.html?green.png
-skip-if(!winWidget) pref(webgl.disable-angle,true)                                == webgl-orientation-test.html?native-gl  wrapper.html?white-top-left.png
-skip-if(!winWidget) pref(webgl.disable-angle,true)                                == webgl-color-test.html?native-gl        wrapper.html?colors.png
-skip-if(!winWidget) pref(webgl.disable-angle,true) pref(webgl.prefer-16bpp,true)  == webgl-color-test.html?native-gl&16bpp  wrapper.html?colors.png
+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
--- a/gfx/gl/GLContext.cpp
+++ b/gfx/gl/GLContext.cpp
@@ -1107,33 +1107,33 @@ GLContext::InitWithPrefix(const char *pr
     }
 
     if (mInitialized) {
         raw_fGetIntegerv(LOCAL_GL_VIEWPORT, mViewportRect);
         raw_fGetIntegerv(LOCAL_GL_SCISSOR_BOX, mScissorRect);
         raw_fGetIntegerv(LOCAL_GL_MAX_TEXTURE_SIZE, &mMaxTextureSize);
         raw_fGetIntegerv(LOCAL_GL_MAX_CUBE_MAP_TEXTURE_SIZE, &mMaxCubeMapTextureSize);
         raw_fGetIntegerv(LOCAL_GL_MAX_RENDERBUFFER_SIZE, &mMaxRenderbufferSize);
-        raw_fGetIntegerv(LOCAL_GL_MAX_VIEWPORT_DIMS, mMaxViewportDims);
 
 #ifdef XP_MACOSX
         if (mWorkAroundDriverBugs) {
             if (mVendor == GLVendor::Intel) {
                 // see bug 737182 for 2D textures, bug 684882 for cube map textures.
                 mMaxTextureSize        = std::min(mMaxTextureSize,        4096);
                 mMaxCubeMapTextureSize = std::min(mMaxCubeMapTextureSize, 512);
                 // for good measure, we align renderbuffers on what we do for 2D textures
                 mMaxRenderbufferSize   = std::min(mMaxRenderbufferSize,   4096);
                 mNeedsTextureSizeChecks = true;
             } else if (mVendor == GLVendor::NVIDIA) {
                 if (nsCocoaFeatures::OnMountainLionOrLater()) {
                     // See bug 879656.  8192 fails, 8191 works.
                     mMaxTextureSize = std::min(mMaxTextureSize, 8191);
                     mMaxRenderbufferSize = std::min(mMaxRenderbufferSize, 8191);
-                } else {
+                }
+                else {
                     // See bug 877949.
                     mMaxTextureSize = std::min(mMaxTextureSize, 4096);
                     mMaxRenderbufferSize = std::min(mMaxRenderbufferSize, 4096);
                 }
 
                 // Part of the bug 879656, but it also doesn't hurt the 877949
                 mNeedsTextureSizeChecks = true;
             }
--- a/gfx/gl/GLContext.h
+++ b/gfx/gl/GLContext.h
@@ -2980,17 +2980,16 @@ protected:
 
     GLint mViewportRect[4];
     GLint mScissorRect[4];
 
     GLint mMaxTextureSize;
     GLint mMaxCubeMapTextureSize;
     GLint mMaxTextureImageSize;
     GLint mMaxRenderbufferSize;
-    GLint mMaxViewportDims[2];
     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
--- a/gfx/gl/GLContextProviderCGL.mm
+++ b/gfx/gl/GLContextProviderCGL.mm
@@ -243,42 +243,34 @@ CreateOffscreenFBOContext(bool aShare = 
 
     SurfaceCaps dummyCaps = SurfaceCaps::Any();
     nsRefPtr<GLContextCGL> glContext = new GLContextCGL(dummyCaps, shareContext, context, true);
 
     return glContext.forget();
 }
 
 already_AddRefed<GLContext>
-GLContextProviderCGL::CreateHeadless()
-{
-    nsRefPtr<GLContextCGL> glContext = CreateOffscreenFBOContext();
-    if (!glContext)
-        return nullptr;
-
-    if (!glContext->Init())
-        return nullptr;
-
-    return glContext.forget();
-}
-
-already_AddRefed<GLContext>
 GLContextProviderCGL::CreateOffscreen(const gfxIntSize& size,
                                       const SurfaceCaps& caps)
 {
-    nsRefPtr<GLContext> glContext = CreateHeadless();
-    if (!glContext->InitOffscreen(ToIntSize(size), caps))
-        return nullptr;
+    nsRefPtr<GLContextCGL> glContext = CreateOffscreenFBOContext();
+    if (glContext &&
+        glContext->Init() &&
+        glContext->InitOffscreen(ToIntSize(size), caps))
+    {
+        return glContext.forget();
+    }
 
-    return glContext.forget();
+    // everything failed
+    return nullptr;
 }
 
 static nsRefPtr<GLContext> gGlobalContext;
 
-GLContext*
+GLContext *
 GLContextProviderCGL::GetGlobalContext()
 {
     if (!sCGLLibrary.EnsureInitialized()) {
         return nullptr;
     }
 
     if (!gGlobalContext) {
         // There are bugs in some older drivers with pbuffers less
--- a/gfx/gl/GLContextProviderEGL.cpp
+++ b/gfx/gl/GLContextProviderEGL.cpp
@@ -873,52 +873,43 @@ GLContextEGL::CreateEGLPixmapOffscreenCo
         return nullptr;
     }
 
     glContext->HoldSurface(thebesSurface);
 
     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::CreateHeadless()
+GLContextProviderEGL::CreateOffscreen(const gfxIntSize& size,
+                                      const SurfaceCaps& caps)
 {
     if (!sEGLLibrary.EnsureInitialized()) {
         return nullptr;
     }
 
     gfxIntSize dummySize = gfxIntSize(16, 16);
-    nsRefPtr<GLContext> glContext;
+    nsRefPtr<GLContextEGL> glContext;
     glContext = GLContextEGL::CreateEGLPBufferOffscreenContext(dummySize);
-    if (!glContext)
-        return nullptr;
-
-    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)
-{
-    nsRefPtr<GLContext> glContext = CreateHeadless();
     if (!glContext)
         return nullptr;
 
     if (!glContext->InitOffscreen(ToIntSize(size), caps))
         return nullptr;
 
     return glContext.forget();
 }
 
 // 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*
+GLContext *
 GLContextProviderEGL::GetGlobalContext()
 {
     return nullptr;
 }
 
 void
 GLContextProviderEGL::Shutdown()
 {
--- a/gfx/gl/GLContextProviderGLX.cpp
+++ b/gfx/gl/GLContextProviderGLX.cpp
@@ -1208,31 +1208,23 @@ DONE_CREATING_PIXMAP:
                                                   true,
                                                   xsurface);
     }
 
     return glContext.forget();
 }
 
 already_AddRefed<GLContext>
-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)
 {
-    nsRefPtr<GLContext> glContext = CreateHeadless();
+    gfxIntSize dummySize = gfxIntSize(16, 16);
+    nsRefPtr<GLContextGLX> glContext =
+        CreateOffscreenPixmapContext(dummySize);
+
     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
@@ -55,20 +55,16 @@ public:
      * @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);
 
-    // Just create a context. We'll add offscreen stuff ourselves.
-    static already_AddRefed<GLContext>
-    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,23 +17,18 @@ GLContextProviderNull::CreateForWindow(n
 already_AddRefed<GLContext>
 GLContextProviderNull::CreateWrappingExisting(void*, void*)
 {
     return nullptr;
 }
 
 already_AddRefed<GLContext>
 GLContextProviderNull::CreateOffscreen(const gfxIntSize&,
-                                       const SurfaceCaps&)
-{
-    return nullptr;
-}
-
-already_AddRefed<GLContext>
-GLContextProviderNull::CreateHeadless()
+                                       const SurfaceCaps&,
+                                       ContextFlags)
 {
     return nullptr;
 }
 
 GLContext*
 GLContextProviderNull::GetGlobalContext(ContextFlags)
 {
     return nullptr;
--- a/gfx/gl/GLContextProviderWGL.cpp
+++ b/gfx/gl/GLContextProviderWGL.cpp
@@ -602,17 +602,18 @@ CreateWindowOffscreenContext()
     nsRefPtr<GLContextWGL> glContext = new GLContextWGL(caps,
                                                         shareContext, true,
                                                         dc, context, win);
 
     return glContext.forget();
 }
 
 already_AddRefed<GLContext>
-GLContextProviderWGL::CreateHeadless()
+GLContextProviderWGL::CreateOffscreen(const gfxIntSize& size,
+                                      const SurfaceCaps& caps)
 {
     if (!sWGLLib.EnsureInitialized()) {
         return nullptr;
     }
 
     nsRefPtr<GLContextWGL> glContext;
 
     // Always try to create a pbuffer context first, because we
@@ -630,28 +631,16 @@ GLContextProviderWGL::CreateHeadless()
     }
 
     if (!glContext ||
         !glContext->Init())
     {
         return nullptr;
     }
 
-    nsRefPtr<GLContext> retGL = glContext;
-    return retGL.forget();
-}
-
-already_AddRefed<GLContext>
-GLContextProviderWGL::CreateOffscreen(const gfxIntSize& size,
-                                      const SurfaceCaps& caps)
-{
-    nsRefPtr<GLContext> glContext = CreateHeadless();
-    if (!glContext)
-        return nullptr;
-
     if (!glContext->InitOffscreen(ToIntSize(size), caps))
         return nullptr;
 
     return glContext.forget();
 }
 
 static nsRefPtr<GLContextWGL> gGlobalContext;
 
--- a/gfx/gl/SurfaceTypes.cpp
+++ b/gfx/gl/SurfaceTypes.cpp
@@ -7,52 +7,52 @@
 
 #include "mozilla/layers/ISurfaceAllocator.h"
 
 namespace mozilla {
 namespace gl {
 
 SurfaceCaps::SurfaceCaps()
 {
-    Clear();
+  Clear();
 }
 
 SurfaceCaps::SurfaceCaps(const SurfaceCaps& other)
 {
-    *this = other;
+  *this = other;
 }
 
 SurfaceCaps&
 SurfaceCaps::operator=(const SurfaceCaps& other)
 {
-    any = other.any;
-    color = other.color;
-    alpha = other.alpha;
-    bpp16 = other.bpp16;
-    depth = other.depth;
-    stencil = other.stencil;
-    antialias = other.antialias;
-    preserve = other.preserve;
-    surfaceAllocator = other.surfaceAllocator;
+  any = other.any;
+  color = other.color;
+  alpha = other.alpha;
+  bpp16 = other.bpp16;
+  depth = other.depth;
+  stencil = other.stencil;
+  antialias = other.antialias;
+  preserve = other.preserve;
+  surfaceAllocator = other.surfaceAllocator;
 
-    return *this;
+  return *this;
 }
 
 void
 SurfaceCaps::Clear()
 {
-    any = false;
-    color = false;
-    alpha = false;
-    bpp16 = false;
-    depth = false;
-    stencil = false;
-    antialias = false;
-    preserve = false;
-    surfaceAllocator = nullptr;
+  any = false;
+  color = false;
+  alpha = false;
+  bpp16 = false;
+  depth = false;
+  stencil = false;
+  antialias = false;
+  preserve = false;
+  surfaceAllocator = nullptr;
 }
 
 SurfaceCaps::~SurfaceCaps()
 {
 }
 
 } // namespace gl
 } // namespace mozilla
--- a/modules/libpref/init/all.js
+++ b/modules/libpref/init/all.js
@@ -3707,17 +3707,17 @@ pref("image.onload.decode.limit", 0);
 // Disable MSAA on mobile.
 pref("gl.msaa-level", 0);
 #else
 pref("gl.msaa-level", 2);
 #endif
 pref("webgl.force-enabled", false);
 pref("webgl.disabled", false);
 pref("webgl.shader_validator", true);
-pref("webgl.disable-angle", false);
+pref("webgl.prefer-native-gl", false);
 pref("webgl.min_capability_mode", false);
 pref("webgl.disable-extensions", false);
 pref("webgl.msaa-force", false);
 pref("webgl.prefer-16bpp", false);
 pref("webgl.default-no-alpha", false);
 pref("webgl.force-layers-readback", false);
 pref("webgl.lose-context-on-memory-preasure", false);
 pref("webgl.can-lose-context-in-foreground", true);