Bug 1339256 - Detect robust_buffer_access_behavior. - r=daoshengmu
authorJeff Gilbert <jgilbert@mozilla.com>
Thu, 09 Feb 2017 20:31:36 -0800
changeset 380786 3a168a559693192762e15079b5ca267d1e0a0b53
parent 380785 70dec4a3877dd1dac1f819baa3557ed21f8b0249
child 380787 ddb0bfb55854f50ab2fcb96f4ed7f2ef4f84e99c
push id38
push userfmarier@mozilla.com
push dateThu, 23 Mar 2017 21:01:33 +0000
reviewersdaoshengmu
bugs1339256
milestone55.0a1
Bug 1339256 - Detect robust_buffer_access_behavior. - r=daoshengmu MozReview-Commit-ID: 4w5D9bOQbY8
dom/canvas/WebGLContext.h
dom/canvas/WebGLContextValidate.cpp
gfx/gl/GLContext.cpp
gfx/gl/GLContext.h
gfx/gl/GLContextCGL.h
gfx/gl/GLContextEAGL.h
gfx/gl/GLContextEGL.h
gfx/gl/GLContextFeatures.cpp
gfx/gl/GLContextGLX.h
gfx/gl/GLContextProviderEGL.cpp
gfx/gl/GLContextProviderGLX.cpp
gfx/gl/GLContextProviderWGL.cpp
gfx/gl/GLContextWGL.h
gfx/gl/GLDefs.h
gfx/gl/GLLibraryEGL.cpp
gfx/gl/GLLibraryEGL.h
gfx/thebes/gfxPrefs.h
modules/libpref/init/all.js
--- a/dom/canvas/WebGLContext.h
+++ b/dom/canvas/WebGLContext.h
@@ -1960,16 +1960,18 @@ protected:
 
     uint64_t mLastUseIndex;
 
     bool mNeedsFakeNoAlpha;
     bool mNeedsFakeNoDepth;
     bool mNeedsFakeNoStencil;
     bool mNeedsEmulatedLoneDepthStencil;
 
+    bool mNeedsIndexValidation;
+
     const bool mAllowFBInvalidation;
 
     bool Has64BitTimestamps() const;
 
     struct ScopedDrawCallWrapper final {
         WebGLContext& mWebGL;
         const bool mFakeNoAlpha;
         const bool mFakeNoDepth;
--- a/dom/canvas/WebGLContextValidate.cpp
+++ b/dom/canvas/WebGLContextValidate.cpp
@@ -720,16 +720,21 @@ WebGLContext::InitAndValidateGL(FailureR
     std::fill_n(mGenericVertexAttribTypes.get(), mGLMaxVertexAttribs, LOCAL_GL_FLOAT);
 
     static const float kDefaultGenericVertexAttribData[4] = { 0, 0, 0, 1 };
     memcpy(mGenericVertexAttrib0Data, kDefaultGenericVertexAttribData,
            sizeof(mGenericVertexAttrib0Data));
 
     mFakeVertexAttrib0BufferObject = 0;
 
+    mNeedsIndexValidation = !gl->IsSupported(gl::GLFeature::robust_buffer_access_behavior);
+    if (gfxPrefs::WebGLForceIndexValidation()) {
+        mNeedsIndexValidation = true;
+    }
+
     return true;
 }
 
 bool
 WebGLContext::ValidateFramebufferTarget(GLenum target,
                                         const char* const info)
 {
     bool isValid = true;
--- a/gfx/gl/GLContext.cpp
+++ b/gfx/gl/GLContext.cpp
@@ -98,16 +98,17 @@ static const char* const sExtensionNames
     "GL_ARB_geometry_shader4",
     "GL_ARB_half_float_pixel",
     "GL_ARB_instanced_arrays",
     "GL_ARB_internalformat_query",
     "GL_ARB_invalidate_subdata",
     "GL_ARB_map_buffer_range",
     "GL_ARB_occlusion_query2",
     "GL_ARB_pixel_buffer_object",
+    "GL_ARB_robust_buffer_access_behavior",
     "GL_ARB_robustness",
     "GL_ARB_sampler_objects",
     "GL_ARB_seamless_cube_map",
     "GL_ARB_shader_texture_lod",
     "GL_ARB_sync",
     "GL_ARB_texture_compression",
     "GL_ARB_texture_float",
     "GL_ARB_texture_non_power_of_two",
@@ -152,16 +153,18 @@ static const char* const sExtensionNames
     "GL_EXT_texture_storage",
     "GL_EXT_timer_query",
     "GL_EXT_transform_feedback",
     "GL_EXT_unpack_subimage",
     "GL_IMG_read_format",
     "GL_IMG_texture_compression_pvrtc",
     "GL_IMG_texture_npot",
     "GL_KHR_debug",
+    "GL_KHR_robust_buffer_access_behavior",
+    "GL_KHR_robustness",
     "GL_KHR_texture_compression_astc_hdr",
     "GL_KHR_texture_compression_astc_ldr",
     "GL_NV_draw_instanced",
     "GL_NV_fence",
     "GL_NV_framebuffer_blit",
     "GL_NV_geometry_program4",
     "GL_NV_half_float",
     "GL_NV_instanced_arrays",
@@ -1138,41 +1141,25 @@ GLContext::LoadMoreSymbols(const char* p
                                                               GLFeature feature)
     {
         const bool useCore = this->IsFeatureProvidedByCoreSymbols(feature);
         const auto list = useCore ? coreList : extList;
         return fnLoadForFeature(list, feature);
     };
 
     if (IsSupported(GLFeature::robustness)) {
-        bool hasRobustness = false;
-
-        if (!hasRobustness && IsExtensionSupported(ARB_robustness)) {
-            const SymLoadStruct symbols[] = {
-                { (PRFuncPtr*) &mSymbols.fGetGraphicsResetStatus, { "GetGraphicsResetStatusARB", nullptr } },
-                END_SYMBOLS
-            };
-            if (fnLoadForExt(symbols, ARB_robustness)) {
-                hasRobustness = true;
-            }
-        }
-
-        if (!hasRobustness && IsExtensionSupported(EXT_robustness)) {
-            const SymLoadStruct symbols[] = {
-                { (PRFuncPtr*) &mSymbols.fGetGraphicsResetStatus, { "GetGraphicsResetStatusEXT", nullptr } },
-                END_SYMBOLS
-            };
-            if (fnLoadForExt(symbols, EXT_robustness)) {
-                hasRobustness = true;
-            }
-        }
-
-        if (!hasRobustness) {
-            MarkUnsupported(GLFeature::robustness);
-        }
+        const SymLoadStruct symbols[] = {
+            { (PRFuncPtr*) &mSymbols.fGetGraphicsResetStatus, { "GetGraphicsResetStatus",
+                                                                "GetGraphicsResetStatusARB",
+                                                                "GetGraphicsResetStatusKHR",
+                                                                "GetGraphicsResetStatusEXT",
+                                                                nullptr } },
+            END_SYMBOLS
+        };
+        fnLoadForFeature(symbols, GLFeature::sync);
     }
 
     if (IsSupported(GLFeature::sync)) {
         const SymLoadStruct symbols[] = {
             { (PRFuncPtr*) &mSymbols.fFenceSync,      { "FenceSync",      nullptr } },
             { (PRFuncPtr*) &mSymbols.fIsSync,         { "IsSync",         nullptr } },
             { (PRFuncPtr*) &mSymbols.fDeleteSync,     { "DeleteSync",     nullptr } },
             { (PRFuncPtr*) &mSymbols.fClientWaitSync, { "ClientWaitSync", nullptr } },
--- a/gfx/gl/GLContext.h
+++ b/gfx/gl/GLContext.h
@@ -116,16 +116,17 @@ enum class GLFeature {
     prim_restart,
     prim_restart_fixed,
     query_counter,
     query_objects,
     query_time_elapsed,
     read_buffer,
     renderbuffer_color_float,
     renderbuffer_color_half_float,
+    robust_buffer_access_behavior,
     robustness,
     sRGB_framebuffer,
     sRGB_texture,
     sampler_objects,
     seamless_cube_map_opt_in,
     shader_texture_lod,
     split_framebuffer,
     standard_derivatives,
@@ -195,20 +196,16 @@ class GLContext
     : public GLLibraryLoader
     , public GenericAtomicRefCounted
     , public SupportsWeakPtr<GLContext>
 {
 public:
     MOZ_DECLARE_WEAKREFERENCE_TYPENAME(GLContext)
 
 // -----------------------------------------------------------------------------
-// basic enums
-public:
-
-// -----------------------------------------------------------------------------
 // basic getters
 public:
 
     /**
      * Returns true if the context is using ANGLE. This should only be overridden
      * for an ANGLE implementation.
      */
     virtual bool IsANGLE() const {
@@ -429,16 +426,17 @@ public:
         ARB_geometry_shader4,
         ARB_half_float_pixel,
         ARB_instanced_arrays,
         ARB_internalformat_query,
         ARB_invalidate_subdata,
         ARB_map_buffer_range,
         ARB_occlusion_query2,
         ARB_pixel_buffer_object,
+        ARB_robust_buffer_access_behavior,
         ARB_robustness,
         ARB_sampler_objects,
         ARB_seamless_cube_map,
         ARB_shader_texture_lod,
         ARB_sync,
         ARB_texture_compression,
         ARB_texture_float,
         ARB_texture_non_power_of_two,
@@ -483,16 +481,18 @@ public:
         EXT_texture_storage,
         EXT_timer_query,
         EXT_transform_feedback,
         EXT_unpack_subimage,
         IMG_read_format,
         IMG_texture_compression_pvrtc,
         IMG_texture_npot,
         KHR_debug,
+        KHR_robust_buffer_access_behavior,
+        KHR_robustness,
         KHR_texture_compression_astc_hdr,
         KHR_texture_compression_astc_ldr,
         NV_draw_instanced,
         NV_fence,
         NV_framebuffer_blit,
         NV_geometry_program4,
         NV_half_float,
         NV_instanced_arrays,
@@ -566,25 +566,16 @@ private:
      */
     void MarkUnsupported(GLFeature feature);
 
     /**
      * Is this feature supported using the core (unsuffixed) symbols?
      */
     bool IsFeatureProvidedByCoreSymbols(GLFeature feature);
 
-// -----------------------------------------------------------------------------
-// Robustness handling
-private:
-    /**
-     * The derived class is expected to provide information on whether or not it
-     * supports robustness.
-     */
-    virtual bool SupportsRobustness() const = 0;
-
 public:
 // -----------------------------------------------------------------------------
 // Error handling
     static const char* GLErrorToString(GLenum aError) {
         switch (aError) {
             case LOCAL_GL_INVALID_ENUM:
                 return "GL_INVALID_ENUM";
             case LOCAL_GL_INVALID_VALUE:
--- a/gfx/gl/GLContextCGL.h
+++ b/gfx/gl/GLContextCGL.h
@@ -50,18 +50,16 @@ public:
     virtual bool IsCurrent() override;
 
     virtual GLenum GetPreferredARGB32Format() const override;
 
     virtual bool SetupLookupFunction() override;
 
     virtual bool IsDoubleBuffered() const override;
 
-    virtual bool SupportsRobustness() const override { return false; }
-
     virtual bool SwapBuffers() override;
 
     virtual void GetWSIInfo(nsCString* const out) const override;
 };
 
 } // namespace gl
 } // namespace mozilla
 
--- a/gfx/gl/GLContextEAGL.h
+++ b/gfx/gl/GLContextEAGL.h
@@ -46,18 +46,16 @@ public:
     virtual bool MakeCurrentImpl(bool aForce) override;
 
     virtual bool IsCurrent() override;
 
     virtual bool SetupLookupFunction() override;
 
     virtual bool IsDoubleBuffered() const override;
 
-    virtual bool SupportsRobustness() const override { return false; }
-
     virtual bool SwapBuffers() override;
 
     virtual void GetWSIInfo(nsCString* const out) const override;
 
     virtual GLuint GetDefaultFramebuffer() override {
         return mBackbufferFB;
     }
 
--- a/gfx/gl/GLContextEGL.h
+++ b/gfx/gl/GLContextEGL.h
@@ -53,20 +53,16 @@ public:
     virtual bool IsDoubleBuffered() const override {
         return mIsDoubleBuffered;
     }
 
     void SetIsDoubleBuffered(bool aIsDB) {
         mIsDoubleBuffered = aIsDB;
     }
 
-    virtual bool SupportsRobustness() const override {
-        return sEGLLibrary.HasRobustness();
-    }
-
     virtual bool IsANGLE() const override {
         return sEGLLibrary.IsANGLE();
     }
 
     virtual bool IsWARP() const override {
         return sEGLLibrary.IsWARP();
     }
 
--- a/gfx/gl/GLContextFeatures.cpp
+++ b/gfx/gl/GLContextFeatures.cpp
@@ -528,23 +528,35 @@ static const FeatureInfo sFeatureInfoArr
         {
             GLContext::ARB_texture_float,
             GLContext::EXT_color_buffer_float,
             GLContext::EXT_color_buffer_half_float,
             GLContext::Extensions_End
         }
     },
     {
+        "robust_buffer_access_behavior",
+        GLVersion::NONE,
+        GLESVersion::NONE,
+        GLContext::Extension_None,
+        {
+            GLContext::ARB_robust_buffer_access_behavior,
+            GLContext::KHR_robust_buffer_access_behavior,
+            GLContext::Extensions_End
+        }
+    },
+    {
         "robustness",
         GLVersion::NONE,
         GLESVersion::NONE,
         GLContext::Extension_None,
         {
             GLContext::ARB_robustness,
             GLContext::EXT_robustness,
+            GLContext::KHR_robustness,
             GLContext::Extensions_End
         }
     },
     {
         "sRGB_framebuffer",
         GLVersion::GL3,
         GLESVersion::ES3,
         GLContext::ARB_framebuffer_sRGB,
--- a/gfx/gl/GLContextGLX.h
+++ b/gfx/gl/GLContextGLX.h
@@ -51,18 +51,16 @@ public:
     virtual bool MakeCurrentImpl(bool aForce) override;
 
     virtual bool IsCurrent() override;
 
     virtual bool SetupLookupFunction() override;
 
     virtual bool IsDoubleBuffered() const override;
 
-    virtual bool SupportsRobustness() const override;
-
     virtual bool SwapBuffers() override;
 
     virtual void GetWSIInfo(nsCString* const out) const override;
 
     // Overrides the current GLXDrawable backing the context and makes the
     // context current.
     bool OverrideDrawable(GLXDrawable drawable);
 
--- a/gfx/gl/GLContextProviderEGL.cpp
+++ b/gfx/gl/GLContextProviderEGL.cpp
@@ -79,17 +79,17 @@ static bool
 CreateConfig(EGLConfig* aConfig);
 
 // append three zeros at the end of attribs list to work around
 // EGL implementation bugs that iterate until they find 0, instead of
 // EGL_NONE. See bug 948406.
 #define EGL_ATTRIBS_LIST_SAFE_TERMINATION_WORKING_AROUND_BUGS \
      LOCAL_EGL_NONE, 0, 0, 0
 
-static EGLint gTerminationAttribs[] = {
+static EGLint kTerminationAttribs[] = {
     EGL_ATTRIBS_LIST_SAFE_TERMINATION_WORKING_AROUND_BUGS
 };
 
 static int
 next_power_of_two(int v)
 {
     v--;
     v |= v >> 1;
@@ -477,41 +477,48 @@ GLContextEGL::CreateGLContext(CreateCont
         *out_failureId = NS_LITERAL_CSTRING("FEATURE_FAILURE_EGL_ES");
         NS_WARNING("Failed to bind API to GLES!");
         return nullptr;
     }
 
     EGLContext eglShareContext = shareContext ? shareContext->mContext
                                               : EGL_NO_CONTEXT;
 
-    nsTArray<EGLint> contextAttribs;
+    std::vector<EGLint> contextAttribs;
 
-    contextAttribs.AppendElement(LOCAL_EGL_CONTEXT_CLIENT_VERSION);
+    contextAttribs.push_back(LOCAL_EGL_CONTEXT_CLIENT_VERSION);
     if (flags & CreateContextFlags::PREFER_ES3)
-        contextAttribs.AppendElement(3);
+        contextAttribs.push_back(3);
     else
-        contextAttribs.AppendElement(2);
+        contextAttribs.push_back(2);
 
-    if (sEGLLibrary.HasRobustness()) {
-//    contextAttribs.AppendElement(LOCAL_EGL_CONTEXT_ROBUST_ACCESS_EXT);
-//    contextAttribs.AppendElement(LOCAL_EGL_TRUE);
+    if (sEGLLibrary.IsExtensionSupported(GLLibraryEGL::KHR_create_context)) {
+        contextAttribs.push_back(LOCAL_EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_KHR);
+        contextAttribs.push_back(LOCAL_EGL_LOSE_CONTEXT_ON_RESET_KHR);
+        contextAttribs.push_back(LOCAL_EGL_CONTEXT_FLAGS_KHR);
+        contextAttribs.push_back(LOCAL_EGL_CONTEXT_OPENGL_ROBUST_ACCESS_BIT_KHR);
+    } else if (sEGLLibrary.IsExtensionSupported(GLLibraryEGL::EXT_create_context_robustness)) {
+        contextAttribs.push_back(LOCAL_EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_EXT);
+        contextAttribs.push_back(LOCAL_EGL_LOSE_CONTEXT_ON_RESET_EXT);
+        contextAttribs.push_back(LOCAL_EGL_CONTEXT_OPENGL_ROBUST_ACCESS_EXT);
+        contextAttribs.push_back(LOCAL_EGL_TRUE);
     }
 
-    for (size_t i = 0; i < MOZ_ARRAY_LENGTH(gTerminationAttribs); i++) {
-      contextAttribs.AppendElement(gTerminationAttribs[i]);
+    for (const auto& cur : kTerminationAttribs) {
+        contextAttribs.push_back(cur);
     }
 
     EGLContext context = sEGLLibrary.fCreateContext(EGL_DISPLAY(),
                                                     config,
                                                     eglShareContext,
-                                                    contextAttribs.Elements());
+                                                    contextAttribs.data());
     if (!context && shareContext) {
         shareContext = nullptr;
         context = sEGLLibrary.fCreateContext(EGL_DISPLAY(), config, EGL_NO_CONTEXT,
-                                             contextAttribs.Elements());
+                                             contextAttribs.data());
     }
     if (!context) {
         *out_failureId = NS_LITERAL_CSTRING("FEATURE_FAILURE_EGL_CREATE");
         NS_WARNING("Failed to create EGLContext!");
         return nullptr;
     }
 
     RefPtr<GLContextEGL> glContext = new GLContextEGL(flags, caps, shareContext,
@@ -542,18 +549,18 @@ TRY_AGAIN_POWER_OF_TWO:
     if (bindToTextureFormat != LOCAL_EGL_NONE) {
         pbattrs.AppendElement(LOCAL_EGL_TEXTURE_TARGET);
         pbattrs.AppendElement(LOCAL_EGL_TEXTURE_2D);
 
         pbattrs.AppendElement(LOCAL_EGL_TEXTURE_FORMAT);
         pbattrs.AppendElement(bindToTextureFormat);
     }
 
-    for (size_t i = 0; i < MOZ_ARRAY_LENGTH(gTerminationAttribs); i++) {
-      pbattrs.AppendElement(gTerminationAttribs[i]);
+    for (const auto& cur : kTerminationAttribs) {
+        pbattrs.AppendElement(cur);
     }
 
     surface = sEGLLibrary.fCreatePbufferSurface(EGL_DISPLAY(), config, &pbattrs[0]);
     if (!surface) {
         if (!is_power_of_two(pbsize.width) ||
             !is_power_of_two(pbsize.height))
         {
             if (!is_power_of_two(pbsize.width))
--- a/gfx/gl/GLContextProviderGLX.cpp
+++ b/gfx/gl/GLContextProviderGLX.cpp
@@ -506,19 +506,21 @@ GLContextGLX::CreateGLContext(CreateCont
 
     do {
         error = false;
 
         GLXContext glxContext = shareContext ? shareContext->mContext : nullptr;
         if (glx.HasCreateContextAttribs()) {
             AutoTArray<int, 11> attrib_list;
             if (glx.HasRobustness()) {
-                int robust_attribs[] = {
-                    LOCAL_GL_CONTEXT_FLAGS_ARB, LOCAL_GL_CONTEXT_ROBUST_ACCESS_BIT_ARB,
-                    LOCAL_GL_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB, LOCAL_GL_LOSE_CONTEXT_ON_RESET_ARB,
+                const int robust_attribs[] = {
+                    LOCAL_GLX_CONTEXT_FLAGS_ARB,
+                    LOCAL_GLX_CONTEXT_ROBUST_ACCESS_BIT_ARB,
+                    LOCAL_GLX_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB,
+                    LOCAL_GLX_LOSE_CONTEXT_ON_RESET_ARB,
                 };
                 attrib_list.AppendElements(robust_attribs, MOZ_ARRAY_LENGTH(robust_attribs));
             }
             if (profile == ContextProfile::OpenGLCore) {
                 int core_attribs[] = {
                     LOCAL_GLX_CONTEXT_MAJOR_VERSION_ARB, 3,
                     LOCAL_GLX_CONTEXT_MINOR_VERSION_ARB, 2,
                     LOCAL_GLX_CONTEXT_FLAGS_ARB, LOCAL_GLX_CONTEXT_CORE_PROFILE_BIT_ARB,
@@ -658,22 +660,16 @@ GLContextGLX::SetupLookupFunction()
 
 bool
 GLContextGLX::IsDoubleBuffered() const
 {
     return mDoubleBuffered;
 }
 
 bool
-GLContextGLX::SupportsRobustness() const
-{
-    return mGLX->HasRobustness();
-}
-
-bool
 GLContextGLX::SwapBuffers()
 {
     if (!mDoubleBuffered)
         return false;
     mGLX->fSwapBuffers(mDisplay, mDrawable);
     return true;
 }
 
--- a/gfx/gl/GLContextProviderWGL.cpp
+++ b/gfx/gl/GLContextProviderWGL.cpp
@@ -357,22 +357,16 @@ GLContextWGL::SetIsDoubleBuffered(bool a
 
 bool
 GLContextWGL::IsDoubleBuffered() const
 {
     return mIsDoubleBuffered;
 }
 
 bool
-GLContextWGL::SupportsRobustness() const
-{
-    return sWGLLib.HasRobustness();
-}
-
-bool
 GLContextWGL::SwapBuffers() {
     if (!mIsDoubleBuffered)
         return false;
     return ::SwapBuffers(mDC);
 }
 
 void
 GLContextWGL::GetWSIInfo(nsCString* const out) const
--- a/gfx/gl/GLContextWGL.h
+++ b/gfx/gl/GLContextWGL.h
@@ -48,18 +48,16 @@ public:
     virtual bool MakeCurrentImpl(bool aForce) override;
 
     virtual bool IsCurrent() override;
 
     void SetIsDoubleBuffered(bool aIsDB);
 
     virtual bool IsDoubleBuffered() const override;
 
-    virtual bool SupportsRobustness() const override;
-
     virtual bool SwapBuffers() override;
 
     virtual bool SetupLookupFunction() override;
 
     virtual void GetWSIInfo(nsCString* const out) const override;
 
     HGLRC Context() { return mContext; }
 
--- a/gfx/gl/GLDefs.h
+++ b/gfx/gl/GLDefs.h
@@ -70,16 +70,19 @@
 #define LOCAL_EGL_D3D11_ELSE_D3D9_DISPLAY_ANGLE         ((EGLNativeDisplayType)-2)
 #define LOCAL_EGL_D3D11_ONLY_DISPLAY_ANGLE              ((EGLNativeDisplayType)-3)
 
 // WGL_NV_DX_interop
 #define LOCAL_WGL_ACCESS_READ_ONLY                      0x0000
 #define LOCAL_WGL_ACCESS_READ_WRITE                     0x0001
 #define LOCAL_WGL_ACCESS_WRITE_DISCARD                  0x0002
 
+// GL_KHR_robustness
+#define LOCAL_GL_CONTEXT_ROBUST_ACCESS                  0x90F3
+
 // Others
 #define LOCAL_EGL_PRESERVED_RESOURCES                   0x3030
 #define LOCAL_EGL_CONTEXT_RESET_NOTIFICATION_STRATEGY_EXT 0x3138
 #define LOCAL_GL_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB 0x8256
 #define LOCAL_GL_CONTEXT_LOST                           0x9242
 #define LOCAL_GL_CONTEXT_FLAGS_ARB                      0x2094
 #define LOCAL_GL_CONTEXT_CORE_PROFILE_BIT_ARB           0x00000001
 #define LOCAL_GL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB  0x00000002
--- a/gfx/gl/GLLibraryEGL.cpp
+++ b/gfx/gl/GLLibraryEGL.cpp
@@ -47,17 +47,18 @@ static const char* sEGLExtensionNames[] 
     "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_image_crop",
     "EGL_ANGLE_platform_angle",
     "EGL_ANGLE_platform_angle_d3d",
-    "EGL_ANGLE_d3d_share_handle_client_buffer"
+    "EGL_ANGLE_d3d_share_handle_client_buffer",
+    "EGL_KHR_create_context",
 };
 
 #if defined(ANDROID)
 
 static PRLibrary* LoadApitraceLibrary()
 {
     // Initialization of gfx prefs here is only needed during the unit tests...
     gfxPrefs::GetSingleton();
--- a/gfx/gl/GLLibraryEGL.h
+++ b/gfx/gl/GLLibraryEGL.h
@@ -100,16 +100,17 @@ public:
         EXT_create_context_robustness,
         KHR_image,
         KHR_fence_sync,
         ANDROID_native_fence_sync,
         EGL_ANDROID_image_crop,
         ANGLE_platform_angle,
         ANGLE_platform_angle_d3d,
         ANGLE_d3d_share_handle_client_buffer,
+        KHR_create_context,
         Extensions_Max
     };
 
     bool IsExtensionSupported(EGLExtensions aKnownExtension) const {
         return mAvailableExtensions[aKnownExtension];
     }
 
     void MarkExtensionUnsupported(EGLExtensions aKnownExtension) {
@@ -322,20 +323,16 @@ public:
     bool HasKHRImageTexture2D() {
         return IsExtensionSupported(KHR_gl_texture_2D_image);
     }
 
     bool HasANGLESurfaceD3DTexture2DShareHandle() {
         return IsExtensionSupported(ANGLE_surface_d3d_texture_2d_share_handle);
     }
 
-    bool HasRobustness() const {
-        return IsExtensionSupported(EXT_create_context_robustness);
-    }
-
     bool ReadbackEGLImage(EGLImage image, gfx::DataSourceSurface* out_surface);
 
     bool EnsureInitialized(bool forceAccel, nsACString* const out_failureId);
 
     void DumpEGLConfig(EGLConfig cfg);
     void DumpEGLConfigs();
 
 private:
--- a/gfx/thebes/gfxPrefs.h
+++ b/gfx/thebes/gfxPrefs.h
@@ -623,16 +623,17 @@ private:
 
   DECL_GFX_PREF(Live, "webgl.disabled",                        WebGLDisabled, bool, false);
 
   DECL_GFX_PREF(Live, "webgl.enable-draft-extensions",         WebGLDraftExtensionsEnabled, bool, false);
   DECL_GFX_PREF(Live, "webgl.enable-privileged-extensions",    WebGLPrivilegedExtensionsEnabled, bool, false);
   DECL_GFX_PREF(Live, "webgl.enable-webgl2",                   WebGL2Enabled, bool, true);
   DECL_GFX_PREF(Live, "webgl.force-enabled",                   WebGLForceEnabled, bool, false);
   DECL_GFX_PREF(Once, "webgl.force-layers-readback",           WebGLForceLayersReadback, bool, false);
+  DECL_GFX_PREF(Live, "webgl.force-index-validation",          WebGLForceIndexValidation, bool, false);
   DECL_GFX_PREF(Live, "webgl.lose-context-on-memory-pressure", WebGLLoseContextOnMemoryPressure, bool, false);
   DECL_GFX_PREF(Live, "webgl.max-warnings-per-context",        WebGLMaxWarningsPerContext, uint32_t, 32);
   DECL_GFX_PREF(Live, "webgl.min_capability_mode",             WebGLMinCapabilityMode, bool, false);
   DECL_GFX_PREF(Live, "webgl.msaa-force",                      WebGLForceMSAA, bool, false);
   DECL_GFX_PREF(Live, "webgl.prefer-16bpp",                    WebGLPrefer16bpp, bool, false);
   DECL_GFX_PREF(Live, "webgl.restore-context-when-visible",    WebGLRestoreWhenVisible, bool, true);
   DECL_GFX_PREF(Live, "webgl.allow-immediate-queries",         WebGLImmediateQueries, bool, false);
   DECL_GFX_PREF(Live, "webgl.allow-fb-invalidation",           WebGLFBInvalidation, bool, false);
--- a/modules/libpref/init/all.js
+++ b/modules/libpref/init/all.js
@@ -4535,16 +4535,17 @@ pref("webgl.disabled", false);
 pref("webgl.disable-angle", false);
 pref("webgl.disable-wgl", 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.force-index-validation", false);
 pref("webgl.lose-context-on-memory-pressure", false);
 pref("webgl.can-lose-context-in-foreground", true);
 pref("webgl.restore-context-when-visible", true);
 pref("webgl.max-warnings-per-context", 32);
 pref("webgl.enable-draft-extensions", false);
 pref("webgl.enable-privileged-extensions", false);
 pref("webgl.bypass-shader-validation", false);
 pref("webgl.disable-fail-if-major-performance-caveat", false);