Bug 989325 - Make WebGLExtensionID a typed enum, and WebGLContext::mExtensions an enumerated array - r=jgilbert
authorBenoit Jacob <bjacob@mozilla.com>
Fri, 25 Apr 2014 22:34:07 -0400
changeset 180734 610d7ccaaa9c9390ff6972f583475ebf3eaaecf5
parent 180733 b00d3a5f4b6fd5ae3beec5ca57691d0f37a875aa
child 180735 c570bcfd29b4d6df0b3ea5d92ec7e12e8f2e0ad3
push id272
push userpvanderbeken@mozilla.com
push dateMon, 05 May 2014 16:31:18 +0000
reviewersjgilbert
bugs989325
milestone31.0a1
Bug 989325 - Make WebGLExtensionID a typed enum, and WebGLContext::mExtensions an enumerated array - r=jgilbert
content/canvas/src/WebGL2Context.cpp
content/canvas/src/WebGLContext.cpp
content/canvas/src/WebGLContext.h
content/canvas/src/WebGLContextDraw.cpp
content/canvas/src/WebGLContextExtensions.cpp
content/canvas/src/WebGLContextGL.cpp
content/canvas/src/WebGLContextState.cpp
content/canvas/src/WebGLContextValidate.cpp
content/canvas/src/WebGLContextVertices.cpp
content/canvas/src/WebGLFramebuffer.cpp
content/canvas/src/WebGLTexture.cpp
content/canvas/src/WebGLTypes.h
--- a/content/canvas/src/WebGL2Context.cpp
+++ b/content/canvas/src/WebGL2Context.cpp
@@ -58,24 +58,24 @@ WebGL2Context::WrapObject(JSContext *cx)
 // WebGL 2 initialisation
 
 bool
 WebGLContext::InitWebGL2()
 {
     MOZ_ASSERT(IsWebGL2(), "WebGLContext is not a WebGL 2 context!");
 
     const WebGLExtensionID sExtensionNativelySupportedArr[] = {
-        ANGLE_instanced_arrays,
-        OES_element_index_uint,
-        OES_standard_derivatives,
-        OES_texture_float,
-        OES_texture_float_linear,
-        OES_vertex_array_object,
-        WEBGL_depth_texture,
-        WEBGL_draw_buffers
+        WebGLExtensionID::ANGLE_instanced_arrays,
+        WebGLExtensionID::OES_element_index_uint,
+        WebGLExtensionID::OES_standard_derivatives,
+        WebGLExtensionID::OES_texture_float,
+        WebGLExtensionID::OES_texture_float_linear,
+        WebGLExtensionID::OES_vertex_array_object,
+        WebGLExtensionID::WEBGL_depth_texture,
+        WebGLExtensionID::WEBGL_draw_buffers
     };
     const GLFeature sFeatureRequiredArr[] = {
         GLFeature::blend_minmax,
         GLFeature::instanced_non_arrays,
         GLFeature::transform_feedback
     };
 
     // check WebGL extensions that are supposed to be natively supported
--- a/content/canvas/src/WebGLContext.cpp
+++ b/content/canvas/src/WebGLContext.cpp
@@ -52,16 +52,17 @@
 #include "mozilla/Telemetry.h"
 
 #include "nsIObserverService.h"
 #include "mozilla/Services.h"
 #include "mozilla/dom/WebGLRenderingContextBinding.h"
 #include "mozilla/dom/BindingUtils.h"
 #include "mozilla/dom/ImageData.h"
 #include "mozilla/ProcessPriorityManager.h"
+#include "mozilla/EnumeratedArrayCycleCollection.h"
 
 #include "Layers.h"
 
 #ifdef MOZ_WIDGET_GONK
 #include "mozilla/layers/ShadowLayers.h"
 #endif
 
 using namespace mozilla;
@@ -257,20 +258,20 @@ WebGLContext::DestroyResourcesAndContext
     mBlackTransparentTextureCubeMap = nullptr;
 
     if (mFakeVertexAttrib0BufferObject) {
         gl->fDeleteBuffers(1, &mFakeVertexAttrib0BufferObject);
     }
 
     // disable all extensions except "WEBGL_lose_context". see bug #927969
     // spec: http://www.khronos.org/registry/webgl/specs/latest/1.0/#5.15.2
-    for (size_t i = 0; i < size_t(WebGLExtensionID_max); ++i) {
+    for (size_t i = 0; i < size_t(WebGLExtensionID::Max); ++i) {
         WebGLExtensionID extension = WebGLExtensionID(i);
 
-        if (!IsExtensionEnabled(extension) || (extension == WEBGL_lose_context))
+        if (!IsExtensionEnabled(extension) || (extension == WebGLExtensionID::WEBGL_lose_context))
             continue;
 
         mExtensions[extension]->MarkLost();
         mExtensions[extension] = nullptr;
     }
 
     // We just got rid of everything, so the context had better
     // have been going away.
@@ -987,17 +988,17 @@ static bool IsShadowCorrect(float shadow
 void
 WebGLContext::ForceClearFramebufferWithDefaultValues(GLbitfield mask, const bool colorAttachmentsMask[sMaxColorAttachments])
 {
     MakeContextCurrent();
 
     bool initializeColorBuffer = 0 != (mask & LOCAL_GL_COLOR_BUFFER_BIT);
     bool initializeDepthBuffer = 0 != (mask & LOCAL_GL_DEPTH_BUFFER_BIT);
     bool initializeStencilBuffer = 0 != (mask & LOCAL_GL_STENCIL_BUFFER_BIT);
-    bool drawBuffersIsEnabled = IsExtensionEnabled(WEBGL_draw_buffers);
+    bool drawBuffersIsEnabled = IsExtensionEnabled(WebGLExtensionID::WEBGL_draw_buffers);
 
     GLenum currentDrawBuffers[WebGLContext::sMaxColorAttachments];
 
     // Fun GL fact: No need to worry about the viewport here, glViewport is just
     // setting up a coordinates transformation, it doesn't affect glClear at all.
 
 #ifdef DEBUG
     // Scope to hide our variables.
--- a/content/canvas/src/WebGLContext.h
+++ b/content/canvas/src/WebGLContext.h
@@ -19,16 +19,17 @@
 #include "nsICanvasRenderingContextInternal.h"
 #include "mozilla/dom/HTMLCanvasElement.h"
 #include "nsWrapperCache.h"
 #include "nsIObserver.h"
 #include "nsLayoutUtils.h"
 
 #include "GLContextProvider.h"
 
+#include "mozilla/EnumeratedArray.h"
 #include "mozilla/LinkedList.h"
 #include "mozilla/CheckedInt.h"
 #include "mozilla/Scoped.h"
 #include "mozilla/gfx/2D.h"
 
 #ifdef XP_MACOSX
 #include "ForceDiscreteGPUHelperCGL.h"
 #endif
@@ -887,43 +888,21 @@ protected:
         // The context is lost, an event has been sent to the script, and the
         // script correctly handled the event. We are waiting for the context to
         // be restored.
         ContextLostAwaitingRestore
     };
 
     // -------------------------------------------------------------------------
     // WebGL extensions (implemented in WebGLContextExtensions.cpp)
-    enum WebGLExtensionID {
-        EXT_color_buffer_half_float,
-        EXT_frag_depth,
-        EXT_sRGB,
-        EXT_texture_filter_anisotropic,
-        OES_element_index_uint,
-        OES_standard_derivatives,
-        OES_texture_float,
-        OES_texture_float_linear,
-        OES_texture_half_float,
-        OES_texture_half_float_linear,
-        OES_vertex_array_object,
-        WEBGL_color_buffer_float,
-        WEBGL_compressed_texture_atc,
-        WEBGL_compressed_texture_etc1,
-        WEBGL_compressed_texture_pvrtc,
-        WEBGL_compressed_texture_s3tc,
-        WEBGL_debug_renderer_info,
-        WEBGL_debug_shaders,
-        WEBGL_depth_texture,
-        WEBGL_lose_context,
-        WEBGL_draw_buffers,
-        ANGLE_instanced_arrays,
-        WebGLExtensionID_max,
-        WebGLExtensionID_unknown_extension
-    };
-    nsTArray<nsRefPtr<WebGLExtensionBase> > mExtensions;
+    typedef EnumeratedArray<WebGLExtensionID,
+                            WebGLExtensionID::Max,
+                            nsRefPtr<WebGLExtensionBase>> ExtensionsArrayType;
+
+    ExtensionsArrayType mExtensions;
 
     // enable an extension. the extension should not be enabled before.
     void EnableExtension(WebGLExtensionID ext);
 
     // returns true if the extension has been enabled by calling getExtension.
     bool IsExtensionEnabled(WebGLExtensionID ext) const;
 
     // returns true if the extension is supported for this JSContext (this decides what getSupportedExtensions exposes)
--- a/content/canvas/src/WebGLContextDraw.cpp
+++ b/content/canvas/src/WebGLContextDraw.cpp
@@ -24,17 +24,17 @@ using namespace mozilla::gl;
 // For a Tegra workaround.
 static const int MAX_DRAW_CALLS_SINCE_FLUSH = 100;
 
 bool
 WebGLContext::DrawInstanced_check(const char* info)
 {
     // This restriction was removed in GLES3, so WebGL2 shouldn't have it.
     if (!IsWebGL2() &&
-        IsExtensionEnabled(ANGLE_instanced_arrays) &&
+        IsExtensionEnabled(WebGLExtensionID::ANGLE_instanced_arrays) &&
         !mBufferFetchingHasPerVertex)
     {
         /* http://www.khronos.org/registry/gles/extensions/ANGLE/ANGLE_instanced_arrays.txt
          *  If all of the enabled vertex attribute arrays that are bound to active
          *  generic attributes in the program have a non-zero divisor, the draw
          *  call should return INVALID_OPERATION.
          *
          * NB: This also appears to apply to NV_instanced_arrays, though the
@@ -189,17 +189,17 @@ WebGLContext::DrawElements_check(GLsizei
             return false;
         }
         first = byteOffset / 2;
     }
     else if (type == LOCAL_GL_UNSIGNED_BYTE) {
         checked_byteCount = count;
         first = byteOffset;
     }
-    else if (type == LOCAL_GL_UNSIGNED_INT && IsExtensionEnabled(OES_element_index_uint)) {
+    else if (type == LOCAL_GL_UNSIGNED_INT && IsExtensionEnabled(WebGLExtensionID::OES_element_index_uint)) {
         checked_byteCount = 4 * CheckedUint32(count);
         if (byteOffset % 4 != 0) {
             ErrorInvalidOperation("%s: invalid byteOffset for UNSIGNED_INT (must be a multiple of 4)", info);
             return false;
         }
         first = byteOffset / 4;
     }
     else {
--- a/content/canvas/src/WebGLContextExtensions.cpp
+++ b/content/canvas/src/WebGLContextExtensions.cpp
@@ -10,56 +10,57 @@
 
 #include "nsString.h"
 #include "mozilla/Preferences.h"
 #include "AccessCheck.h"
 
 using namespace mozilla;
 using namespace mozilla::gl;
 
-// must match WebGLContext::WebGLExtensionID
-static const char *sExtensionNames[] = {
-    "EXT_color_buffer_half_float",
-    "EXT_frag_depth",
-    "EXT_sRGB",
-    "EXT_texture_filter_anisotropic",
-    "OES_element_index_uint",
-    "OES_standard_derivatives",
-    "OES_texture_float",
-    "OES_texture_float_linear",
-    "OES_texture_half_float",
-    "OES_texture_half_float_linear",
-    "OES_vertex_array_object",
-    "WEBGL_color_buffer_float",
-    "WEBGL_compressed_texture_atc",
-    "WEBGL_compressed_texture_etc1",
-    "WEBGL_compressed_texture_pvrtc",
-    "WEBGL_compressed_texture_s3tc",
-    "WEBGL_debug_renderer_info",
-    "WEBGL_debug_shaders",
-    "WEBGL_depth_texture",
-    "WEBGL_lose_context",
-    "WEBGL_draw_buffers",
-    "ANGLE_instanced_arrays"
-};
-
 /* static */ const char*
 WebGLContext::GetExtensionString(WebGLExtensionID ext)
 {
-    static_assert(MOZ_ARRAY_LENGTH(sExtensionNames) == size_t(WebGLExtensionID_max),
-                  "Mismatched lengths for sFeatureInfoInfos and GLFeature enums");
+    // must match WebGLExtensionID.
+    // Once we can use variadic templates, EnumeratedArray should get a constructor
+    // allowing to initialize it directly without using this auxiliary plain array.
+    static const char *kExtensionNames[] = {
+        "ANGLE_instanced_arrays",
+        "EXT_color_buffer_half_float",
+        "EXT_frag_depth",
+        "EXT_sRGB",
+        "EXT_texture_filter_anisotropic",
+        "OES_element_index_uint",
+        "OES_standard_derivatives",
+        "OES_texture_float",
+        "OES_texture_float_linear",
+        "OES_texture_half_float",
+        "OES_texture_half_float_linear",
+        "OES_vertex_array_object",
+        "WEBGL_color_buffer_float",
+        "WEBGL_compressed_texture_atc",
+        "WEBGL_compressed_texture_etc1",
+        "WEBGL_compressed_texture_pvrtc",
+        "WEBGL_compressed_texture_s3tc",
+        "WEBGL_debug_renderer_info",
+        "WEBGL_debug_shaders",
+        "WEBGL_depth_texture",
+        "WEBGL_draw_buffers",
+        "WEBGL_lose_context"
+    };
 
-    MOZ_ASSERT(ext < WebGLExtensionID_max, "unknown extension!");
+    typedef EnumeratedArray<WebGLExtensionID, WebGLExtensionID::Max, const char*>
+            names_array_t;
+    static const names_array_t kExtensionNamesEnumeratedArray(kExtensionNames);
 
-    return sExtensionNames[ext];
+    return kExtensionNamesEnumeratedArray[ext];
 }
 
 bool
 WebGLContext::IsExtensionEnabled(WebGLExtensionID ext) const {
-    return mExtensions.SafeElementAt(ext);
+    return mExtensions[ext];
 }
 
 bool WebGLContext::IsExtensionSupported(JSContext *cx, WebGLExtensionID ext) const
 {
     bool allowPrivilegedExts = false;
 
     // Chrome contexts need access to debug information even when
     // webgl.disable-extensions is set. This is used in the graphics
@@ -67,19 +68,19 @@ bool WebGLContext::IsExtensionSupported(
     if (xpc::AccessCheck::isChrome(js::GetContextCompartment(cx)))
         allowPrivilegedExts = true;
 
     if (Preferences::GetBool("webgl.enable-privileged-extensions", false))
         allowPrivilegedExts = true;
 
     if (allowPrivilegedExts) {
         switch (ext) {
-            case WEBGL_debug_renderer_info:
+            case WebGLExtensionID::WEBGL_debug_renderer_info:
                 return true;
-            case WEBGL_debug_shaders:
+            case WebGLExtensionID::WEBGL_debug_shaders:
                 return true;
             default:
                 // For warnings-as-errors.
                 break;
         }
     }
 
     return IsExtensionSupported(ext);
@@ -87,74 +88,74 @@ bool WebGLContext::IsExtensionSupported(
 
 bool WebGLContext::IsExtensionSupported(WebGLExtensionID ext) const
 {
     if (mDisableExtensions) {
         return false;
     }
 
     switch (ext) {
-        case OES_element_index_uint:
+        case WebGLExtensionID::OES_element_index_uint:
             return gl->IsSupported(GLFeature::element_index_uint);
-        case OES_standard_derivatives:
+        case WebGLExtensionID::OES_standard_derivatives:
             return gl->IsSupported(GLFeature::standard_derivatives);
-        case WEBGL_lose_context:
+        case WebGLExtensionID::WEBGL_lose_context:
             // We always support this extension.
             return true;
-        case OES_texture_float:
+        case WebGLExtensionID::OES_texture_float:
             return gl->IsSupported(GLFeature::texture_float);
-        case OES_texture_float_linear:
+        case WebGLExtensionID::OES_texture_float_linear:
             return gl->IsSupported(GLFeature::texture_float_linear);
-        case OES_texture_half_float:
+        case WebGLExtensionID::OES_texture_half_float:
             // If we have Feature::texture_half_float, we must not be on ES2
             // and need to translate HALF_FLOAT_OES -> HALF_FLOAT.  We do that
             // right before making the relevant calls.
             return gl->IsExtensionSupported(GLContext::OES_texture_half_float) ||
                    gl->IsSupported(GLFeature::texture_half_float);
-        case OES_texture_half_float_linear:
+        case WebGLExtensionID::OES_texture_half_float_linear:
             return gl->IsSupported(GLFeature::texture_half_float_linear);
-        case WEBGL_color_buffer_float:
+        case WebGLExtensionID::WEBGL_color_buffer_float:
             return WebGLExtensionColorBufferFloat::IsSupported(this);
-        case EXT_color_buffer_half_float:
+        case WebGLExtensionID::EXT_color_buffer_half_float:
             return WebGLExtensionColorBufferHalfFloat::IsSupported(this);
-        case OES_vertex_array_object:
+        case WebGLExtensionID::OES_vertex_array_object:
             return WebGLExtensionVertexArray::IsSupported(this);
-        case EXT_texture_filter_anisotropic:
+        case WebGLExtensionID::EXT_texture_filter_anisotropic:
             return gl->IsExtensionSupported(GLContext::EXT_texture_filter_anisotropic);
-        case WEBGL_compressed_texture_s3tc:
+        case WebGLExtensionID::WEBGL_compressed_texture_s3tc:
             if (gl->IsExtensionSupported(GLContext::EXT_texture_compression_s3tc)) {
                 return true;
             }
             else if (gl->IsExtensionSupported(GLContext::EXT_texture_compression_dxt1) &&
                      gl->IsExtensionSupported(GLContext::ANGLE_texture_compression_dxt3) &&
                      gl->IsExtensionSupported(GLContext::ANGLE_texture_compression_dxt5))
             {
                 return true;
             }
             return false;
-        case WEBGL_compressed_texture_atc:
+        case WebGLExtensionID::WEBGL_compressed_texture_atc:
             return gl->IsExtensionSupported(GLContext::AMD_compressed_ATC_texture);
-        case WEBGL_compressed_texture_etc1:
+        case WebGLExtensionID::WEBGL_compressed_texture_etc1:
             return gl->IsExtensionSupported(GLContext::OES_compressed_ETC1_RGB8_texture);
-        case WEBGL_compressed_texture_pvrtc:
+        case WebGLExtensionID::WEBGL_compressed_texture_pvrtc:
             return gl->IsExtensionSupported(GLContext::IMG_texture_compression_pvrtc);
-        case WEBGL_depth_texture:
+        case WebGLExtensionID::WEBGL_depth_texture:
             // WEBGL_depth_texture supports DEPTH_STENCIL textures
             if (!gl->IsSupported(GLFeature::packed_depth_stencil)) {
                 return false;
             }
             return gl->IsSupported(GLFeature::depth_texture) ||
                    gl->IsExtensionSupported(GLContext::ANGLE_depth_texture);
-        case ANGLE_instanced_arrays:
+        case WebGLExtensionID::ANGLE_instanced_arrays:
             return WebGLExtensionInstancedArrays::IsSupported(this);
-        case EXT_sRGB:
+        case WebGLExtensionID::EXT_sRGB:
             return WebGLExtensionSRGB::IsSupported(this);
-        case WEBGL_draw_buffers:
+        case WebGLExtensionID::WEBGL_draw_buffers:
             return WebGLExtensionDrawBuffers::IsSupported(this);
-        case EXT_frag_depth:
+        case WebGLExtensionID::EXT_frag_depth:
             return WebGLExtensionFragDepth::IsSupported(this);
         default:
             // For warnings-as-errors.
             break;
     }
 // Uncomment this switch for any new extensions
 #if 0
     if (Preferences::GetBool("webgl.enable-draft-extensions", false) || IsWebGL2()) {
@@ -178,61 +179,61 @@ CompareWebGLExtensionName(const nsACStri
 JSObject*
 WebGLContext::GetExtension(JSContext *cx, const nsAString& aName, ErrorResult& rv)
 {
     if (IsContextLost())
         return nullptr;
 
     NS_LossyConvertUTF16toASCII name(aName);
 
-    WebGLExtensionID ext = WebGLExtensionID_unknown_extension;
+    WebGLExtensionID ext = WebGLExtensionID::Unknown;
 
     // step 1: figure what extension is wanted
-    for (size_t i = 0; i < size_t(WebGLExtensionID_max); i++)
+    for (size_t i = 0; i < size_t(WebGLExtensionID::Max); i++)
     {
         WebGLExtensionID extension = WebGLExtensionID(i);
 
         if (CompareWebGLExtensionName(name, GetExtensionString(extension))) {
             ext = extension;
             break;
         }
     }
 
-    if (ext == WebGLExtensionID_unknown_extension)
+    if (ext == WebGLExtensionID::Unknown)
     {
         /**
          * We keep backward compatibility for these deprecated vendor-prefixed
          * alias. Do not add new ones anymore. Hide it behind the
          * webgl.enable-draft-extensions flag instead.
          */
         if (CompareWebGLExtensionName(name, "MOZ_WEBGL_lose_context")) {
-            ext = WEBGL_lose_context;
+            ext = WebGLExtensionID::WEBGL_lose_context;
         }
         else if (CompareWebGLExtensionName(name, "MOZ_WEBGL_compressed_texture_s3tc")) {
-            ext = WEBGL_compressed_texture_s3tc;
+            ext = WebGLExtensionID::WEBGL_compressed_texture_s3tc;
         }
         else if (CompareWebGLExtensionName(name, "MOZ_WEBGL_compressed_texture_atc")) {
-            ext = WEBGL_compressed_texture_atc;
+            ext = WebGLExtensionID::WEBGL_compressed_texture_atc;
         }
         else if (CompareWebGLExtensionName(name, "MOZ_WEBGL_compressed_texture_pvrtc")) {
-            ext = WEBGL_compressed_texture_pvrtc;
+            ext = WebGLExtensionID::WEBGL_compressed_texture_pvrtc;
         }
         else if (CompareWebGLExtensionName(name, "MOZ_WEBGL_depth_texture")) {
-            ext = WEBGL_depth_texture;
+            ext = WebGLExtensionID::WEBGL_depth_texture;
         }
 
-        if (ext != WebGLExtensionID_unknown_extension) {
+        if (ext != WebGLExtensionID::Unknown) {
             GenerateWarning("getExtension('%s'): MOZ_ prefixed WebGL extension strings are deprecated. "
                             "Support for them will be removed in the future. Use unprefixed extension strings. "
                             "To get draft extensions, set the webgl.enable-draft-extensions preference.",
                             name.get());
         }
     }
 
-    if (ext == WebGLExtensionID_unknown_extension) {
+    if (ext == WebGLExtensionID::Unknown) {
         return nullptr;
     }
 
     // step 2: check if the extension is supported
     if (!IsExtensionSupported(cx, ext)) {
         return nullptr;
     }
 
@@ -242,86 +243,84 @@ WebGLContext::GetExtension(JSContext *cx
     }
 
     return WebGLObjectAsJSObject(cx, mExtensions[ext].get(), rv);
 }
 
 void
 WebGLContext::EnableExtension(WebGLExtensionID ext)
 {
-    mExtensions.EnsureLengthAtLeast(ext + 1);
-
     MOZ_ASSERT(IsExtensionEnabled(ext) == false);
 
     WebGLExtensionBase* obj = nullptr;
     switch (ext) {
-        case OES_element_index_uint:
+        case WebGLExtensionID::OES_element_index_uint:
             obj = new WebGLExtensionElementIndexUint(this);
             break;
-        case OES_standard_derivatives:
+        case WebGLExtensionID::OES_standard_derivatives:
             obj = new WebGLExtensionStandardDerivatives(this);
             break;
-        case EXT_texture_filter_anisotropic:
+        case WebGLExtensionID::EXT_texture_filter_anisotropic:
             obj = new WebGLExtensionTextureFilterAnisotropic(this);
             break;
-        case WEBGL_lose_context:
+        case WebGLExtensionID::WEBGL_lose_context:
             obj = new WebGLExtensionLoseContext(this);
             break;
-        case WEBGL_compressed_texture_s3tc:
+        case WebGLExtensionID::WEBGL_compressed_texture_s3tc:
             obj = new WebGLExtensionCompressedTextureS3TC(this);
             break;
-        case WEBGL_compressed_texture_atc:
+        case WebGLExtensionID::WEBGL_compressed_texture_atc:
             obj = new WebGLExtensionCompressedTextureATC(this);
             break;
-        case WEBGL_compressed_texture_etc1:
+        case WebGLExtensionID::WEBGL_compressed_texture_etc1:
             obj = new WebGLExtensionCompressedTextureETC1(this);
             break;
-        case WEBGL_compressed_texture_pvrtc:
+        case WebGLExtensionID::WEBGL_compressed_texture_pvrtc:
             obj = new WebGLExtensionCompressedTexturePVRTC(this);
             break;
-        case WEBGL_debug_renderer_info:
+        case WebGLExtensionID::WEBGL_debug_renderer_info:
             obj = new WebGLExtensionDebugRendererInfo(this);
             break;
-        case WEBGL_debug_shaders:
+        case WebGLExtensionID::WEBGL_debug_shaders:
             obj = new WebGLExtensionDebugShaders(this);
             break;
-        case WEBGL_depth_texture:
+        case WebGLExtensionID::WEBGL_depth_texture:
             obj = new WebGLExtensionDepthTexture(this);
             break;
-        case OES_texture_float:
+        case WebGLExtensionID::OES_texture_float:
             obj = new WebGLExtensionTextureFloat(this);
             break;
-        case OES_texture_float_linear:
+        case WebGLExtensionID::OES_texture_float_linear:
             obj = new WebGLExtensionTextureFloatLinear(this);
             break;
-        case OES_texture_half_float:
+        case WebGLExtensionID::OES_texture_half_float:
             obj = new WebGLExtensionTextureHalfFloat(this);
             break;
-        case OES_texture_half_float_linear:
+        case WebGLExtensionID::OES_texture_half_float_linear:
             obj = new WebGLExtensionTextureHalfFloatLinear(this);
             break;
-        case WEBGL_color_buffer_float:
+        case WebGLExtensionID::WEBGL_color_buffer_float:
             obj = new WebGLExtensionColorBufferFloat(this);
             break;
-        case EXT_color_buffer_half_float:
+        case WebGLExtensionID::EXT_color_buffer_half_float:
             obj = new WebGLExtensionColorBufferHalfFloat(this);
             break;
-        case WEBGL_draw_buffers:
+        case WebGLExtensionID::WEBGL_draw_buffers:
             obj = new WebGLExtensionDrawBuffers(this);
             break;
-        case OES_vertex_array_object:
+        case WebGLExtensionID::OES_vertex_array_object:
             obj = new WebGLExtensionVertexArray(this);
             break;
-        case ANGLE_instanced_arrays:
+        case WebGLExtensionID::ANGLE_instanced_arrays:
             obj = new WebGLExtensionInstancedArrays(this);
             break;
-        case EXT_sRGB:
+        case WebGLExtensionID::EXT_sRGB:
             obj = new WebGLExtensionSRGB(this);
             break;
-        case EXT_frag_depth:
+        case WebGLExtensionID::EXT_frag_depth:
             obj = new WebGLExtensionFragDepth(this);
             break;
         default:
             MOZ_ASSERT(false, "should not get there.");
     }
 
     mExtensions[ext] = obj;
 }
@@ -330,34 +329,34 @@ void
 WebGLContext::GetSupportedExtensions(JSContext *cx, Nullable< nsTArray<nsString> > &retval)
 {
     retval.SetNull();
     if (IsContextLost())
         return;
 
     nsTArray<nsString>& arr = retval.SetValue();
 
-    for (size_t i = 0; i < size_t(WebGLExtensionID_max); i++)
+    for (size_t i = 0; i < size_t(WebGLExtensionID::Max); i++)
     {
         WebGLExtensionID extension = WebGLExtensionID(i);
 
         if (IsExtensionSupported(cx, extension)) {
             arr.AppendElement(NS_ConvertUTF8toUTF16(GetExtensionString(extension)));
         }
     }
 
     /**
      * We keep backward compatibility for these deprecated vendor-prefixed
      * alias. Do not add new ones anymore. Hide it behind the
      * webgl.enable-draft-extensions flag instead.
      */
-    if (IsExtensionSupported(cx, WEBGL_lose_context))
+    if (IsExtensionSupported(cx, WebGLExtensionID::WEBGL_lose_context))
         arr.AppendElement(NS_LITERAL_STRING("MOZ_WEBGL_lose_context"));
-    if (IsExtensionSupported(cx, WEBGL_compressed_texture_s3tc))
+    if (IsExtensionSupported(cx, WebGLExtensionID::WEBGL_compressed_texture_s3tc))
         arr.AppendElement(NS_LITERAL_STRING("MOZ_WEBGL_compressed_texture_s3tc"));
-    if (IsExtensionSupported(cx, WEBGL_compressed_texture_atc))
+    if (IsExtensionSupported(cx, WebGLExtensionID::WEBGL_compressed_texture_atc))
         arr.AppendElement(NS_LITERAL_STRING("MOZ_WEBGL_compressed_texture_atc"));
-    if (IsExtensionSupported(cx, WEBGL_compressed_texture_pvrtc))
+    if (IsExtensionSupported(cx, WebGLExtensionID::WEBGL_compressed_texture_pvrtc))
         arr.AppendElement(NS_LITERAL_STRING("MOZ_WEBGL_compressed_texture_pvrtc"));
-    if (IsExtensionSupported(cx, WEBGL_depth_texture))
+    if (IsExtensionSupported(cx, WebGLExtensionID::WEBGL_depth_texture))
         arr.AppendElement(NS_LITERAL_STRING("MOZ_WEBGL_depth_texture"));
 }
 
--- a/content/canvas/src/WebGLContextGL.cpp
+++ b/content/canvas/src/WebGLContextGL.cpp
@@ -899,17 +899,17 @@ WebGLContext::GenerateMipmap(GLenum targ
 
     if (!tex->IsFirstImagePowerOfTwo())
         return ErrorInvalidOperation("generateMipmap: Level zero of texture does not have power-of-two width and height.");
 
     GLenum internalFormat = tex->ImageInfoAt(imageTarget, 0).InternalFormat();
     if (IsTextureFormatCompressed(internalFormat))
         return ErrorInvalidOperation("generateMipmap: Texture data at level zero is compressed.");
 
-    if (IsExtensionEnabled(WEBGL_depth_texture) &&
+    if (IsExtensionEnabled(WebGLExtensionID::WEBGL_depth_texture) &&
         (IsGLDepthFormat(internalFormat) || IsGLDepthStencilFormat(internalFormat)))
     {
         return ErrorInvalidOperation("generateMipmap: "
                                      "A texture that has a base internal format of "
                                      "DEPTH_COMPONENT or DEPTH_STENCIL isn't supported");
     }
 
     if (!tex->AreAllLevel0ImageInfosEqual())
@@ -1083,17 +1083,17 @@ WebGLContext::GetFramebufferAttachmentPa
         ErrorInvalidOperation("getFramebufferAttachmentParameter: cannot query framebuffer 0");
         return JS::NullValue();
     }
 
     if (attachment != LOCAL_GL_DEPTH_ATTACHMENT &&
         attachment != LOCAL_GL_STENCIL_ATTACHMENT &&
         attachment != LOCAL_GL_DEPTH_STENCIL_ATTACHMENT)
     {
-        if (IsExtensionEnabled(WEBGL_draw_buffers))
+        if (IsExtensionEnabled(WebGLExtensionID::WEBGL_draw_buffers))
         {
             if (attachment < LOCAL_GL_COLOR_ATTACHMENT0 ||
                 attachment >= GLenum(LOCAL_GL_COLOR_ATTACHMENT0 + mGLMaxColorAttachments))
             {
                 ErrorInvalidEnumInfo("getFramebufferAttachmentParameter: attachment", attachment);
                 return JS::NullValue();
             }
 
@@ -1108,35 +1108,35 @@ WebGLContext::GetFramebufferAttachmentPa
 
     MakeContextCurrent();
 
     const WebGLFramebuffer::Attachment& fba = mBoundFramebuffer->GetAttachment(attachment);
 
     if (fba.Renderbuffer()) {
         switch (pname) {
             case LOCAL_GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING_EXT:
-                if (IsExtensionEnabled(EXT_sRGB)) {
+                if (IsExtensionEnabled(WebGLExtensionID::EXT_sRGB)) {
                     const GLenum internalFormat = fba.Renderbuffer()->InternalFormat();
                     return (internalFormat == LOCAL_GL_SRGB_EXT ||
                             internalFormat == LOCAL_GL_SRGB_ALPHA_EXT ||
                             internalFormat == LOCAL_GL_SRGB8_ALPHA8_EXT) ?
                         JS::NumberValue(uint32_t(LOCAL_GL_SRGB_EXT)) :
                         JS::NumberValue(uint32_t(LOCAL_GL_LINEAR));
                 }
                 break;
 
             case LOCAL_GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE:
                 return JS::NumberValue(uint32_t(LOCAL_GL_RENDERBUFFER));
 
             case LOCAL_GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME:
                 return WebGLObjectAsJSValue(cx, fba.Renderbuffer(), rv);
 
             case LOCAL_GL_FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE: {
-                if (!IsExtensionEnabled(EXT_color_buffer_half_float) &&
-                    !IsExtensionEnabled(WEBGL_color_buffer_float))
+                if (!IsExtensionEnabled(WebGLExtensionID::EXT_color_buffer_half_float) &&
+                    !IsExtensionEnabled(WebGLExtensionID::WEBGL_color_buffer_float))
                 {
                     break;
                 }
 
                 if (attachment == LOCAL_GL_DEPTH_STENCIL_ATTACHMENT) {
                     ErrorInvalidOperation("getFramebufferAttachmentParameter: Cannot get component"
                                           " type of a depth-stencil attachment.");
                     return JS::NullValue();
@@ -1171,17 +1171,17 @@ WebGLContext::GetFramebufferAttachmentPa
             }
         }
 
         ErrorInvalidEnumInfo("getFramebufferAttachmentParameter: pname", pname);
         return JS::NullValue();
     } else if (fba.Texture()) {
         switch (pname) {
              case LOCAL_GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING_EXT:
-                if (IsExtensionEnabled(EXT_sRGB)) {
+                if (IsExtensionEnabled(WebGLExtensionID::EXT_sRGB)) {
                     const GLenum internalFormat =
                         fba.Texture()->ImageInfoBase().InternalFormat();
                     return (internalFormat == LOCAL_GL_SRGB_EXT ||
                             internalFormat == LOCAL_GL_SRGB_ALPHA_EXT) ?
                         JS::NumberValue(uint32_t(LOCAL_GL_SRGB_EXT)) :
                         JS::NumberValue(uint32_t(LOCAL_GL_LINEAR));
                 }
                 break;
@@ -1198,18 +1198,18 @@ WebGLContext::GetFramebufferAttachmentPa
             case LOCAL_GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE: {
                 GLenum face = fba.TexImageTarget();
                 if (face == LOCAL_GL_TEXTURE_2D)
                     face = 0;
                 return JS::Int32Value(face);
             }
 
             case LOCAL_GL_FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE: {
-                if (!IsExtensionEnabled(EXT_color_buffer_half_float) &&
-                    !IsExtensionEnabled(WEBGL_color_buffer_float))
+                if (!IsExtensionEnabled(WebGLExtensionID::EXT_color_buffer_half_float) &&
+                    !IsExtensionEnabled(WebGLExtensionID::WEBGL_color_buffer_float))
                 {
                     break;
                 }
 
                 if (attachment == LOCAL_GL_DEPTH_STENCIL_ATTACHMENT) {
                     ErrorInvalidOperation("getFramebufferAttachmentParameter: cannot component"
                                           " type of depth-stencil attachments.");
                     return JS::NullValue();
@@ -1530,17 +1530,17 @@ void WebGLContext::TexParameter_base(GLe
                 case LOCAL_GL_REPEAT:
                     tex->SetWrapT(intParam);
                     break;
                 default:
                     pnameAndParamAreIncompatible = true;
             }
             break;
         case LOCAL_GL_TEXTURE_MAX_ANISOTROPY_EXT:
-            if (IsExtensionEnabled(EXT_texture_filter_anisotropic)) {
+            if (IsExtensionEnabled(WebGLExtensionID::EXT_texture_filter_anisotropic)) {
                 if (floatParamPtr && floatParam < 1.f)
                     paramValueInvalid = true;
                 else if (intParamPtr && intParam < 1)
                     paramValueInvalid = true;
             }
             else
                 pnameAndParamAreIncompatible = true;
             break;
@@ -1593,17 +1593,17 @@ WebGLContext::GetTexParameter(GLenum tar
         case LOCAL_GL_TEXTURE_WRAP_S:
         case LOCAL_GL_TEXTURE_WRAP_T:
         {
             GLint i = 0;
             gl->fGetTexParameteriv(target, pname, &i);
             return JS::NumberValue(uint32_t(i));
         }
         case LOCAL_GL_TEXTURE_MAX_ANISOTROPY_EXT:
-            if (IsExtensionEnabled(EXT_texture_filter_anisotropic)) {
+            if (IsExtensionEnabled(WebGLExtensionID::EXT_texture_filter_anisotropic)) {
                 GLfloat f = 0.f;
                 gl->fGetTexParameterfv(target, pname, &f);
                 return JS::DoubleValue(f);
             }
 
             ErrorInvalidEnumInfo("getTexParameter: parameter", pname);
             break;
 
@@ -1790,17 +1790,17 @@ WebGLContext::Hint(GLenum target, GLenum
 
     bool isValid = false;
 
     switch (target) {
         case LOCAL_GL_GENERATE_MIPMAP_HINT:
             isValid = true;
             break;
         case LOCAL_GL_FRAGMENT_SHADER_DERIVATIVE_HINT:
-            if (IsExtensionEnabled(OES_standard_derivatives))
+            if (IsExtensionEnabled(WebGLExtensionID::OES_standard_derivatives))
                 isValid = true;
             break;
     }
 
     if (!isValid)
         return ErrorInvalidEnum("hint: invalid hint");
 
     MakeContextCurrent();
@@ -2113,18 +2113,18 @@ WebGLContext::ReadPixels(GLint x, GLint 
         case LOCAL_GL_UNSIGNED_SHORT_4_4_4_4:
         case LOCAL_GL_UNSIGNED_SHORT_5_5_5_1:
         case LOCAL_GL_UNSIGNED_SHORT_5_6_5:
             isReadTypeValid = true;
             bytesPerPixel = 2;
             requiredDataType = js::ArrayBufferView::TYPE_UINT16;
             break;
         case LOCAL_GL_FLOAT:
-            if (IsExtensionEnabled(WEBGL_color_buffer_float) ||
-                IsExtensionEnabled(EXT_color_buffer_half_float))
+            if (IsExtensionEnabled(WebGLExtensionID::WEBGL_color_buffer_float) ||
+                IsExtensionEnabled(WebGLExtensionID::EXT_color_buffer_half_float))
             {
                 isReadTypeValid = true;
                 isReadTypeFloat = true;
                 bytesPerPixel = 4*channels;
                 requiredDataType = js::ArrayBufferView::TYPE_FLOAT32;
             }
             break;
     }
@@ -2373,26 +2373,26 @@ WebGLContext::RenderbufferStorage(GLenum
     case LOCAL_GL_DEPTH_STENCIL:
         // We emulate this in WebGLRenderbuffer if we don't have the requisite extension.
         internalformatForGL = LOCAL_GL_DEPTH24_STENCIL8;
         break;
     case LOCAL_GL_SRGB8_ALPHA8_EXT:
         break;
     case LOCAL_GL_RGB16F:
     case LOCAL_GL_RGBA16F: {
-        bool hasExtensions = IsExtensionEnabled(OES_texture_half_float) &&
-                             IsExtensionEnabled(EXT_color_buffer_half_float);
+        bool hasExtensions = IsExtensionEnabled(WebGLExtensionID::OES_texture_half_float) &&
+                             IsExtensionEnabled(WebGLExtensionID::EXT_color_buffer_half_float);
         if (!hasExtensions)
             return ErrorInvalidEnumInfo("renderbufferStorage: internalformat", target);
         break;
     }
     case LOCAL_GL_RGB32F:
     case LOCAL_GL_RGBA32F: {
-        bool hasExtensions = IsExtensionEnabled(OES_texture_float) &&
-                             IsExtensionEnabled(WEBGL_color_buffer_float);
+        bool hasExtensions = IsExtensionEnabled(WebGLExtensionID::OES_texture_float) &&
+                             IsExtensionEnabled(WebGLExtensionID::WEBGL_color_buffer_float);
         if (!hasExtensions)
             return ErrorInvalidEnumInfo("renderbufferStorage: internalformat", target);
         break;
     }
     default:
         return ErrorInvalidEnumInfo("renderbufferStorage: internalformat", internalformat);
     }
 
@@ -2980,23 +2980,23 @@ WebGLContext::CompileShader(WebGLShader 
         resources.MaxVertexUniformVectors = mGLMaxVertexUniformVectors;
         resources.MaxVaryingVectors = mGLMaxVaryingVectors;
         resources.MaxVertexTextureImageUnits = mGLMaxVertexTextureImageUnits;
         resources.MaxCombinedTextureImageUnits = mGLMaxTextureUnits;
         resources.MaxTextureImageUnits = mGLMaxTextureImageUnits;
         resources.MaxFragmentUniformVectors = mGLMaxFragmentUniformVectors;
         resources.MaxDrawBuffers = mGLMaxDrawBuffers;
 
-        if (IsExtensionEnabled(EXT_frag_depth))
+        if (IsExtensionEnabled(WebGLExtensionID::EXT_frag_depth))
             resources.EXT_frag_depth = 1;
 
-        if (IsExtensionEnabled(OES_standard_derivatives))
+        if (IsExtensionEnabled(WebGLExtensionID::OES_standard_derivatives))
             resources.OES_standard_derivatives = 1;
 
-        if (IsExtensionEnabled(WEBGL_draw_buffers))
+        if (IsExtensionEnabled(WebGLExtensionID::WEBGL_draw_buffers))
             resources.EXT_draw_buffers = 1;
 
         // Tell ANGLE to allow highp in frag shaders. (unless disabled)
         // If underlying GLES doesn't have highp in frag shaders, it should complain anyways.
         resources.FragmentPrecisionHigh = mDisableFragHighP ? 0 : 1;
 
         if (gl->WorkAroundDriverBugs()) {
 #ifdef XP_MACOSX
--- a/content/canvas/src/WebGLContextState.cpp
+++ b/content/canvas/src/WebGLContextState.cpp
@@ -112,17 +112,17 @@ WebGLContext::GetParameter(JSContext* cx
                 return JS::Int32Value(MINVALUE_GL_MAX_RENDERBUFFER_SIZE);
 
             default:
                 // Return the real value; we're not overriding this one
                 break;
         }
     }
 
-    if (IsExtensionEnabled(WEBGL_draw_buffers)) {
+    if (IsExtensionEnabled(WebGLExtensionID::WEBGL_draw_buffers)) {
         if (pname == LOCAL_GL_MAX_COLOR_ATTACHMENTS) {
             return JS::Int32Value(mGLMaxColorAttachments);
 
         } else if (pname == LOCAL_GL_MAX_DRAW_BUFFERS) {
             return JS::Int32Value(mGLMaxDrawBuffers);
 
         } else if (pname >= LOCAL_GL_DRAW_BUFFER0 &&
                    pname < GLenum(LOCAL_GL_DRAW_BUFFER0 + mGLMaxDrawBuffers))
@@ -139,17 +139,17 @@ WebGLContext::GetParameter(JSContext* cx
             if (iv == GLint(LOCAL_GL_COLOR_ATTACHMENT0 + pname - LOCAL_GL_DRAW_BUFFER0)) {
                 return JS::Int32Value(LOCAL_GL_BACK);
             }
 
             return JS::Int32Value(LOCAL_GL_NONE);
         }
     }
 
-    if (IsExtensionEnabled(OES_vertex_array_object)) {
+    if (IsExtensionEnabled(WebGLExtensionID::OES_vertex_array_object)) {
         if (pname == LOCAL_GL_VERTEX_ARRAY_BINDING) {
             if (mBoundVertexArray == mDefaultVertexArray){
                 return WebGLObjectAsJSValue(cx, (WebGLVertexArray *) nullptr, rv);
             }
 
             return WebGLObjectAsJSValue(cx, mBoundVertexArray.get(), rv);
         }
     }
@@ -177,17 +177,17 @@ WebGLContext::GetParameter(JSContext* cx
         case LOCAL_GL_SHADING_LANGUAGE_VERSION:
             return StringValue(cx, "WebGL GLSL ES 1.0", rv);
 
             // Privileged string params exposed by WEBGL_debug_renderer_info:
         case UNMASKED_VENDOR_WEBGL:
         case UNMASKED_RENDERER_WEBGL: {
             // The privilege check is done in WebGLContext::IsExtensionSupported.
             // So here we just have to check that the extension is enabled.
-            if (!IsExtensionEnabled(WEBGL_debug_renderer_info)) {
+            if (!IsExtensionEnabled(WebGLExtensionID::WEBGL_debug_renderer_info)) {
                 break;
             }
             GLenum glstringname = LOCAL_GL_NONE;
             if (pname == UNMASKED_VENDOR_WEBGL) {
                 glstringname = LOCAL_GL_VENDOR;
             } else if (pname == UNMASKED_RENDERER_WEBGL) {
                 glstringname = LOCAL_GL_RENDERER;
             }
@@ -241,17 +241,17 @@ WebGLContext::GetParameter(JSContext* cx
         case LOCAL_GL_ALPHA_BITS:
         case LOCAL_GL_DEPTH_BITS:
         case LOCAL_GL_STENCIL_BITS: {
             GLint i = 0;
             gl->fGetIntegerv(pname, &i);
             return JS::Int32Value(i);
         }
         case LOCAL_GL_FRAGMENT_SHADER_DERIVATIVE_HINT: {
-            if (IsExtensionEnabled(OES_standard_derivatives)) {
+            if (IsExtensionEnabled(WebGLExtensionID::OES_standard_derivatives)) {
                 GLint i = 0;
                 gl->fGetIntegerv(pname, &i);
                 return JS::Int32Value(i);
             } else {
                 break;
             }
         }
         case LOCAL_GL_MAX_TEXTURE_SIZE:
@@ -299,17 +299,17 @@ WebGLContext::GetParameter(JSContext* cx
             gl->fGetIntegerv(pname, &i);
             GLuint i_unsigned(i); // this is where -1 becomes 2^32-1
             double i_double(i_unsigned); // pass as FP value to allow large values such as 2^32-1.
             return JS::DoubleValue(i_double);
         }
 
         // float
         case LOCAL_GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT: {
-            if (IsExtensionEnabled(EXT_texture_filter_anisotropic)) {
+            if (IsExtensionEnabled(WebGLExtensionID::EXT_texture_filter_anisotropic)) {
                 GLfloat f = 0.f;
                 gl->fGetFloatv(pname, &f);
                 return JS::DoubleValue(f);
             } else {
                 break;
             }
         }
         case LOCAL_GL_DEPTH_CLEAR_VALUE:
--- a/content/canvas/src/WebGLContextValidate.cpp
+++ b/content/canvas/src/WebGLContextValidate.cpp
@@ -307,67 +307,67 @@ WebGLContext::BaseTexFormat(GLenum inter
         internalFormat == LOCAL_GL_LUMINANCE ||
         internalFormat == LOCAL_GL_LUMINANCE_ALPHA ||
         internalFormat == LOCAL_GL_RGB ||
         internalFormat == LOCAL_GL_RGBA)
     {
         return internalFormat;
     }
 
-    if (IsExtensionEnabled(EXT_sRGB)) {
+    if (IsExtensionEnabled(WebGLExtensionID::EXT_sRGB)) {
         if (internalFormat == LOCAL_GL_SRGB)
             return LOCAL_GL_RGB;
 
         if (internalFormat == LOCAL_GL_SRGB_ALPHA)
             return LOCAL_GL_RGBA;
     }
 
-    if (IsExtensionEnabled(WEBGL_compressed_texture_atc)) {
+    if (IsExtensionEnabled(WebGLExtensionID::WEBGL_compressed_texture_atc)) {
         if (internalFormat == LOCAL_GL_ATC_RGB)
             return LOCAL_GL_RGB;
 
         if (internalFormat == LOCAL_GL_ATC_RGBA_EXPLICIT_ALPHA ||
             internalFormat == LOCAL_GL_ATC_RGBA_INTERPOLATED_ALPHA)
         {
             return LOCAL_GL_RGBA;
         }
     }
 
-    if (IsExtensionEnabled(WEBGL_compressed_texture_etc1)) {
+    if (IsExtensionEnabled(WebGLExtensionID::WEBGL_compressed_texture_etc1)) {
         if (internalFormat == LOCAL_GL_ETC1_RGB8_OES)
             return LOCAL_GL_RGB;
     }
 
-    if (IsExtensionEnabled(WEBGL_compressed_texture_pvrtc)) {
+    if (IsExtensionEnabled(WebGLExtensionID::WEBGL_compressed_texture_pvrtc)) {
         if (internalFormat == LOCAL_GL_COMPRESSED_RGB_PVRTC_2BPPV1 ||
             internalFormat == LOCAL_GL_COMPRESSED_RGB_PVRTC_4BPPV1)
         {
             return LOCAL_GL_RGB;
         }
 
         if (internalFormat == LOCAL_GL_COMPRESSED_RGBA_PVRTC_2BPPV1 ||
             internalFormat == LOCAL_GL_COMPRESSED_RGBA_PVRTC_4BPPV1)
         {
             return LOCAL_GL_RGBA;
         }
     }
 
-    if (IsExtensionEnabled(WEBGL_compressed_texture_s3tc)) {
+    if (IsExtensionEnabled(WebGLExtensionID::WEBGL_compressed_texture_s3tc)) {
         if (internalFormat == LOCAL_GL_COMPRESSED_RGB_S3TC_DXT1_EXT)
             return LOCAL_GL_RGB;
 
         if (internalFormat == LOCAL_GL_COMPRESSED_RGBA_S3TC_DXT1_EXT ||
             internalFormat == LOCAL_GL_COMPRESSED_RGBA_S3TC_DXT3_EXT ||
             internalFormat == LOCAL_GL_COMPRESSED_RGBA_S3TC_DXT5_EXT)
         {
             return LOCAL_GL_RGBA;
         }
     }
 
-    if (IsExtensionEnabled(WEBGL_depth_texture)) {
+    if (IsExtensionEnabled(WebGLExtensionID::WEBGL_depth_texture)) {
         if (internalFormat == LOCAL_GL_DEPTH_COMPONENT ||
             internalFormat == LOCAL_GL_DEPTH_COMPONENT16 ||
             internalFormat == LOCAL_GL_DEPTH_COMPONENT32)
         {
             return LOCAL_GL_DEPTH_COMPONENT;
         }
 
         if (internalFormat == LOCAL_GL_DEPTH_STENCIL ||
@@ -596,75 +596,75 @@ WebGLContext::ValidateTexImageFormat(GLe
         ErrorInvalidEnumWithName(this, "invalid format", format, func);
         return false;
     }
 
     /* WEBGL_depth_texture added formats */
     if (format == LOCAL_GL_DEPTH_COMPONENT ||
         format == LOCAL_GL_DEPTH_STENCIL)
     {
-        bool validFormat = IsExtensionEnabled(WEBGL_depth_texture);
+        bool validFormat = IsExtensionEnabled(WebGLExtensionID::WEBGL_depth_texture);
         if (!validFormat)
             ErrorInvalidEnum("%s: invalid format %s: need WEBGL_depth_texture enabled",
                              InfoFrom(func), NameFrom(format));
         return validFormat;
     }
 
     /* EXT_sRGB added formats */
     if (format == LOCAL_GL_SRGB ||
         format == LOCAL_GL_SRGB_ALPHA)
     {
-        bool validFormat = IsExtensionEnabled(EXT_sRGB);
+        bool validFormat = IsExtensionEnabled(WebGLExtensionID::EXT_sRGB);
         if (!validFormat)
             ErrorInvalidEnum("%s: invalid format %s: need EXT_sRGB enabled",
                              InfoFrom(func), NameFrom(format));
         return validFormat;
     }
 
     /* WEBGL_compressed_texture_atc added formats */
     if (format == LOCAL_GL_ATC_RGB ||
         format == LOCAL_GL_ATC_RGBA_EXPLICIT_ALPHA ||
         format == LOCAL_GL_ATC_RGBA_INTERPOLATED_ALPHA)
     {
-        bool validFormat = IsExtensionEnabled(WEBGL_compressed_texture_atc);
+        bool validFormat = IsExtensionEnabled(WebGLExtensionID::WEBGL_compressed_texture_atc);
         if (!validFormat)
             ErrorInvalidEnum("%s: invalid format %s: need WEBGL_compressed_texture_atc enabled",
                              InfoFrom(func), NameFrom(format));
         return validFormat;
     }
 
     // WEBGL_compressed_texture_etc1
     if (format == LOCAL_GL_ETC1_RGB8_OES) {
-        bool validFormat = IsExtensionEnabled(WEBGL_compressed_texture_etc1);
+        bool validFormat = IsExtensionEnabled(WebGLExtensionID::WEBGL_compressed_texture_etc1);
         if (!validFormat)
             ErrorInvalidEnum("%s: invalid format %s: need WEBGL_compressed_texture_etc1 enabled",
                              InfoFrom(func), NameFrom(format));
         return validFormat;
     }
 
 
     if (format == LOCAL_GL_COMPRESSED_RGB_PVRTC_2BPPV1 ||
         format == LOCAL_GL_COMPRESSED_RGB_PVRTC_4BPPV1 ||
         format == LOCAL_GL_COMPRESSED_RGBA_PVRTC_2BPPV1 ||
         format == LOCAL_GL_COMPRESSED_RGBA_PVRTC_4BPPV1)
     {
-        bool validFormat = IsExtensionEnabled(WEBGL_compressed_texture_pvrtc);
+        bool validFormat = IsExtensionEnabled(WebGLExtensionID::WEBGL_compressed_texture_pvrtc);
         if (!validFormat)
             ErrorInvalidEnum("%s: invalid format %s: need WEBGL_compressed_texture_pvrtc enabled",
                              InfoFrom(func), NameFrom(format));
         return validFormat;
     }
 
 
     if (format == LOCAL_GL_COMPRESSED_RGB_S3TC_DXT1_EXT ||
         format == LOCAL_GL_COMPRESSED_RGBA_S3TC_DXT1_EXT ||
         format == LOCAL_GL_COMPRESSED_RGBA_S3TC_DXT3_EXT ||
         format == LOCAL_GL_COMPRESSED_RGBA_S3TC_DXT5_EXT)
     {
-        bool validFormat = IsExtensionEnabled(WEBGL_compressed_texture_s3tc);
+        bool validFormat = IsExtensionEnabled(WebGLExtensionID::WEBGL_compressed_texture_s3tc);
         if (!validFormat)
             ErrorInvalidEnum("%s: invalid format %s: need WEBGL_compressed_texture_s3tc enabled",
                              InfoFrom(func), NameFrom(format));
         return validFormat;
     }
 
     ErrorInvalidEnumWithName(this, "invalid format", format, func);
 
@@ -708,38 +708,38 @@ WebGLContext::ValidateTexImageType(GLenu
         type == LOCAL_GL_UNSIGNED_SHORT_4_4_4_4 ||
         type == LOCAL_GL_UNSIGNED_SHORT_5_5_5_1)
     {
         return true;
     }
 
     /* OES_texture_float added types */
     if (type == LOCAL_GL_FLOAT) {
-        bool validType = IsExtensionEnabled(OES_texture_float);
+        bool validType = IsExtensionEnabled(WebGLExtensionID::OES_texture_float);
         if (!validType)
             ErrorInvalidEnum("%s: invalid type %s: need OES_texture_float enabled",
                              InfoFrom(func), NameFrom(type));
         return validType;
     }
 
     /* OES_texture_half_float add types */
     if (type == LOCAL_GL_HALF_FLOAT_OES) {
-        bool validType = IsExtensionEnabled(OES_texture_half_float);
+        bool validType = IsExtensionEnabled(WebGLExtensionID::OES_texture_half_float);
         if (!validType)
             ErrorInvalidEnum("%s: invalid type %s: need OES_texture_half_float enabled",
                              InfoFrom(func), NameFrom(type));
         return validType;
     }
 
     /* WEBGL_depth_texture added types */
     if (type == LOCAL_GL_UNSIGNED_SHORT ||
         type == LOCAL_GL_UNSIGNED_INT ||
         type == LOCAL_GL_UNSIGNED_INT_24_8)
     {
-        bool validType = IsExtensionEnabled(WEBGL_depth_texture);
+        bool validType = IsExtensionEnabled(WebGLExtensionID::WEBGL_depth_texture);
         if (!validType)
             ErrorInvalidEnum("%s: invalid type %s: need WEBGL_depth_texture enabled",
                              InfoFrom(func), NameFrom(type));
         return validType;
     }
 
     ErrorInvalidEnumWithName(this, "invalid type", type, func);
     return false;
--- a/content/canvas/src/WebGLContextVertices.cpp
+++ b/content/canvas/src/WebGLContextVertices.cpp
@@ -259,17 +259,17 @@ WebGLContext::GetVertexAttrib(JSContext*
             if (pname == LOCAL_GL_VERTEX_ATTRIB_ARRAY_SIZE)
                 return JS::Int32Value(i);
             MOZ_ASSERT(pname == LOCAL_GL_VERTEX_ATTRIB_ARRAY_TYPE);
             return JS::NumberValue(uint32_t(i));
         }
 
         case LOCAL_GL_VERTEX_ATTRIB_ARRAY_DIVISOR:
         {
-            if (IsExtensionEnabled(ANGLE_instanced_arrays))
+            if (IsExtensionEnabled(WebGLExtensionID::ANGLE_instanced_arrays))
             {
                 return JS::Int32Value(mBoundVertexArray->mAttribs[index].divisor);
             }
             break;
         }
 
         case LOCAL_GL_CURRENT_VERTEX_ATTRIB:
         {
--- a/content/canvas/src/WebGLFramebuffer.cpp
+++ b/content/canvas/src/WebGLFramebuffer.cpp
@@ -825,17 +825,17 @@ WebGLFramebuffer::CheckAndInitializeAtta
 
     return true;
 }
 
 bool WebGLFramebuffer::CheckColorAttachmentNumber(GLenum attachment, const char* functionName) const
 {
     const char* const errorFormating = "%s: attachment: invalid enum value 0x%x";
 
-    if (mContext->IsExtensionEnabled(WebGLContext::WEBGL_draw_buffers)) {
+    if (mContext->IsExtensionEnabled(WebGLExtensionID::WEBGL_draw_buffers)) {
         if (attachment < LOCAL_GL_COLOR_ATTACHMENT0 ||
             attachment >= GLenum(LOCAL_GL_COLOR_ATTACHMENT0 + mContext->mGLMaxColorAttachments))
         {
             mContext->ErrorInvalidEnum(errorFormating, functionName, attachment);
             return false;
         }
     } else if (attachment != LOCAL_GL_COLOR_ATTACHMENT0) {
         if (attachment > LOCAL_GL_COLOR_ATTACHMENT0 &&
--- a/content/canvas/src/WebGLTexture.cpp
+++ b/content/canvas/src/WebGLTexture.cpp
@@ -329,17 +329,17 @@ WebGLTexture::ResolvedFakeBlackStatus() 
                             "with some level 0 image having width or height not a power of two, and with a wrap mode "
                             "different from CLAMP_TO_EDGE.", msg_rendering_as_black);
                 mFakeBlackStatus = WebGLTextureFakeBlackStatus::IncompleteTexture;
             }
         }
     }
 
     if (ImageInfoBase().mType == LOCAL_GL_FLOAT &&
-        !Context()->IsExtensionEnabled(WebGLContext::OES_texture_float_linear))
+        !Context()->IsExtensionEnabled(WebGLExtensionID::OES_texture_float_linear))
     {
         if (mMinFilter == LOCAL_GL_LINEAR ||
             mMinFilter == LOCAL_GL_LINEAR_MIPMAP_LINEAR ||
             mMinFilter == LOCAL_GL_LINEAR_MIPMAP_NEAREST ||
             mMinFilter == LOCAL_GL_NEAREST_MIPMAP_LINEAR)
         {
             mContext->GenerateWarning("%s is a texture with a linear minification filter, "
                                       "which is not compatible with gl.FLOAT by default. "
@@ -349,17 +349,17 @@ WebGLTexture::ResolvedFakeBlackStatus() 
         else if (mMagFilter == LOCAL_GL_LINEAR)
         {
             mContext->GenerateWarning("%s is a texture with a linear magnification filter, "
                                       "which is not compatible with gl.FLOAT by default. "
                                       "Try enabling the OES_texture_float_linear extension if supported.", msg_rendering_as_black);
             mFakeBlackStatus = WebGLTextureFakeBlackStatus::IncompleteTexture;
         }
     } else if (ImageInfoBase().mType == LOCAL_GL_HALF_FLOAT_OES &&
-               !Context()->IsExtensionEnabled(WebGLContext::OES_texture_half_float_linear))
+               !Context()->IsExtensionEnabled(WebGLExtensionID::OES_texture_half_float_linear))
     {
         if (mMinFilter == LOCAL_GL_LINEAR ||
             mMinFilter == LOCAL_GL_LINEAR_MIPMAP_LINEAR ||
             mMinFilter == LOCAL_GL_LINEAR_MIPMAP_NEAREST ||
             mMinFilter == LOCAL_GL_NEAREST_MIPMAP_LINEAR)
         {
             mContext->GenerateWarning("%s is a texture with a linear minification filter, "
                                       "which is not compatible with gl.HALF_FLOAT by default. "
--- a/content/canvas/src/WebGLTypes.h
+++ b/content/canvas/src/WebGLTypes.h
@@ -138,11 +138,39 @@ MOZ_BEGIN_ENUM_CLASS(WebGLTexImageFunc, 
     TexImage,
     TexSubImage,
     CopyTexImage,
     CopyTexSubImage,
     CompTexImage,
     CompTexSubImage,
 MOZ_END_ENUM_CLASS(WebGLTexImageFunc)
 
+// Please keep extensions in alphabetic order.
+MOZ_BEGIN_ENUM_CLASS(WebGLExtensionID, uint8_t)
+    ANGLE_instanced_arrays,
+    EXT_color_buffer_half_float,
+    EXT_frag_depth,
+    EXT_sRGB,
+    EXT_texture_filter_anisotropic,
+    OES_element_index_uint,
+    OES_standard_derivatives,
+    OES_texture_float,
+    OES_texture_float_linear,
+    OES_texture_half_float,
+    OES_texture_half_float_linear,
+    OES_vertex_array_object,
+    WEBGL_color_buffer_float,
+    WEBGL_compressed_texture_atc,
+    WEBGL_compressed_texture_etc1,
+    WEBGL_compressed_texture_pvrtc,
+    WEBGL_compressed_texture_s3tc,
+    WEBGL_debug_renderer_info,
+    WEBGL_debug_shaders,
+    WEBGL_depth_texture,
+    WEBGL_draw_buffers,
+    WEBGL_lose_context,
+    Max,
+    Unknown
+MOZ_END_ENUM_CLASS(WebGLExtensionID)
+
 } // namespace mozilla
 
 #endif