Bug 779611 - part 3 - port WebGL extensions to WebIDL bindings, refactor them - r=bz,jgilbert
authorBenoit Jacob <bjacob@mozilla.com>
Wed, 03 Oct 2012 17:13:05 -0400
changeset 115423 0984909abb53f9513ed1dea302b840281958e3a4
parent 115422 ed26b7f1a02a685a43ad0db2ad8c9734a9d1e392
child 115424 a5a4c320de967082e9049a82d044d1aef40371cc
push id1708
push userakeybl@mozilla.com
push dateMon, 19 Nov 2012 21:10:21 +0000
treeherdermozilla-beta@27b14fe50103 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbz, jgilbert
bugs779611
milestone18.0a1
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
Bug 779611 - part 3 - port WebGL extensions to WebIDL bindings, refactor them - r=bz,jgilbert
content/canvas/src/Makefile.in
content/canvas/src/WebGLContext.cpp
content/canvas/src/WebGLContext.h
content/canvas/src/WebGLContextGL.cpp
content/canvas/src/WebGLExtensionBase.cpp
content/canvas/src/WebGLExtensionCompressedTextureATC.cpp
content/canvas/src/WebGLExtensionCompressedTexturePVRTC.cpp
content/canvas/src/WebGLExtensionCompressedTextureS3TC.cpp
content/canvas/src/WebGLExtensionDepthTexture.cpp
content/canvas/src/WebGLExtensionLoseContext.cpp
content/canvas/src/WebGLExtensionStandardDerivatives.cpp
content/canvas/src/WebGLExtensionTextureFilterAnisotropic.cpp
content/canvas/src/WebGLExtensionTextureFloat.cpp
content/canvas/src/WebGLExtensions.h
dom/base/nsDOMClassInfo.cpp
dom/base/nsDOMClassInfo.h
dom/base/nsDOMClassInfoClasses.h
dom/bindings/Bindings.conf
dom/webidl/WebGLRenderingContext.webidl
js/xpconnect/src/dom_quickstubs.qsconf
--- a/content/canvas/src/Makefile.in
+++ b/content/canvas/src/Makefile.in
@@ -16,16 +16,17 @@ MODULE		= content
 LIBRARY_NAME	= gkconcvs_s
 LIBXUL_LIBRARY  = 1
 
 EXPORTS = \
 	CustomQS_Canvas.h \
 	CustomQS_Canvas2D.h \
 	WebGLContext.h \
 	WebGLElementArrayCache.h \
+	WebGLExtensions.h \
 	$(NULL)
 
 EXPORTS_NAMESPACES = mozilla/dom
 
 EXPORTS_mozilla/dom = \
   ImageData.h \
   $(NULL)
 
@@ -42,25 +43,27 @@ CPPSRCS	= \
 ifdef MOZ_WEBGL
 
 CPPSRCS += \
 	WebGLContext.cpp \
 	WebGLContextGL.cpp \
 	WebGLContextUtils.cpp \
 	WebGLContextReporter.cpp \
 	WebGLContextValidate.cpp \
+	WebGLTexelConversions.cpp \
+	WebGLElementArrayCache.cpp \
+	WebGLExtensionBase.cpp \
+	WebGLExtensionCompressedTextureATC.cpp \
+	WebGLExtensionCompressedTexturePVRTC.cpp \
+	WebGLExtensionCompressedTextureS3TC.cpp \
+	WebGLExtensionDepthTexture.cpp \
+	WebGLExtensionLoseContext.cpp \
 	WebGLExtensionStandardDerivatives.cpp \
 	WebGLExtensionTextureFilterAnisotropic.cpp \
-	WebGLExtensionLoseContext.cpp \
-	WebGLTexelConversions.cpp \
-	WebGLExtensionCompressedTextureS3TC.cpp \
-	WebGLExtensionCompressedTextureATC.cpp \
-	WebGLExtensionCompressedTexturePVRTC.cpp \
-	WebGLExtensionDepthTexture.cpp \
-	WebGLElementArrayCache.cpp \
+	WebGLExtensionTextureFloat.cpp \
 	$(NULL)
 
 DEFINES += -DUSE_ANGLE
 USE_ANGLE=1
 
 else
 
 CPPSRCS += WebGLContextNotSupported.cpp
--- a/content/canvas/src/WebGLContext.cpp
+++ b/content/canvas/src/WebGLContext.cpp
@@ -36,21 +36,23 @@
 
 #include "mozilla/Preferences.h"
 #include "mozilla/Services.h"
 #include "mozilla/Telemetry.h"
 
 #include "nsIObserverService.h"
 #include "mozilla/Services.h"
 #include "mozilla/dom/WebGLRenderingContextBinding.h"
+#include "mozilla/dom/BindingUtils.h"
 
 #include "Layers.h"
 
 using namespace mozilla;
 using namespace mozilla::gl;
+using namespace mozilla::dom;
 using namespace mozilla::layers;
 
 NS_IMPL_ISUPPORTS1(WebGLMemoryPressureObserver, nsIObserver)
 
 NS_IMETHODIMP
 WebGLMemoryPressureObserver::Observe(nsISupports* aSubject,
                                      const char* aTopic,
                                      const PRUnichar* aSomeData)
@@ -84,17 +86,16 @@ WebGLContextOptions::WebGLContextOptions
     if (Preferences::GetBool("webgl.default-no-alpha", false))
         alpha = false;
 }
 
 WebGLContext::WebGLContext()
     : gl(nullptr)
 {
     SetIsDOMBinding();
-    mExtensions.SetLength(WebGLExtensionID_number_of_extensions);
 
     mGeneration = 0;
     mInvalidated = false;
     mResetLayer = true;
     mOptionsFrozen = false;
 
     mActiveTexture = 0;
     mWebGLError = LOCAL_GL_NO_ERROR;
@@ -909,16 +910,21 @@ WebGLContext::GetContextAttributes(Error
     {
         rv.Throw(NS_ERROR_FAILURE);
         return NULL;
     }
 
     return obj;
 }
 
+bool
+WebGLContext::IsExtensionEnabled(WebGLExtensionID ext) {
+    return mExtensions.SafeElementAt(ext);
+}
+
 /* [noscript] DOMString mozGetUnderlyingParamString(in WebGLenum pname); */
 NS_IMETHODIMP
 WebGLContext::MozGetUnderlyingParamString(uint32_t pname, nsAString& retval)
 {
     if (!IsContextStable())
         return NS_OK;
 
     retval.SetIsVoid(true);
@@ -994,115 +1000,122 @@ bool WebGLContext::IsExtensionSupported(
             break;
         default:
             MOZ_ASSERT(false, "should not get there.");
     }
 
     return isSupported;
 }
 
-nsIWebGLExtension*
-WebGLContext::GetExtension(const nsAString& aName)
+JSObject*
+WebGLContext::GetExtension(JSContext *cx, const nsAString& aName)
 {
     if (!IsContextStable())
         return nullptr;
 
     if (mDisableExtensions) {
         return nullptr;
     }
 
     WebGLExtensionID ext = WebGLExtensionID_unknown_extension;
 
+    // step 1: figure what extension is wanted
     if (aName.Equals(NS_LITERAL_STRING("OES_texture_float"),
         nsCaseInsensitiveStringComparator()))
     {
-        if (IsExtensionSupported(OES_texture_float))
-            ext = OES_texture_float;
+        ext = OES_texture_float;
     }
     else if (aName.Equals(NS_LITERAL_STRING("OES_standard_derivatives"),
              nsCaseInsensitiveStringComparator()))
     {
-        if (IsExtensionSupported(OES_standard_derivatives))
-            ext = OES_standard_derivatives;
+        ext = OES_standard_derivatives;
     }
     else if (aName.Equals(NS_LITERAL_STRING("EXT_texture_filter_anisotropic"),
              nsCaseInsensitiveStringComparator()))
     {
-        if (IsExtensionSupported(EXT_texture_filter_anisotropic))
-            ext = EXT_texture_filter_anisotropic;
+        ext = EXT_texture_filter_anisotropic;
     }
     else if (aName.Equals(NS_LITERAL_STRING("MOZ_WEBGL_lose_context"),
              nsCaseInsensitiveStringComparator()))
     {
-        if (IsExtensionSupported(WEBGL_lose_context))
-            ext = WEBGL_lose_context;
+        ext = WEBGL_lose_context;
     }
     else if (aName.Equals(NS_LITERAL_STRING("MOZ_WEBGL_compressed_texture_s3tc"),
              nsCaseInsensitiveStringComparator()))
     {
-        if (IsExtensionSupported(WEBGL_compressed_texture_s3tc))
-            ext = WEBGL_compressed_texture_s3tc;
+        ext = WEBGL_compressed_texture_s3tc;
     }
     else if (aName.Equals(NS_LITERAL_STRING("MOZ_WEBGL_compressed_texture_atc"),
              nsCaseInsensitiveStringComparator()))
     {
-        if (IsExtensionSupported(WEBGL_compressed_texture_atc))
-            ext = WEBGL_compressed_texture_atc;
+        ext = WEBGL_compressed_texture_atc;
     }
     else if (aName.Equals(NS_LITERAL_STRING("MOZ_WEBGL_compressed_texture_pvrtc"),
              nsCaseInsensitiveStringComparator()))
     {
-        if (IsExtensionSupported(WEBGL_compressed_texture_pvrtc))
-            ext = WEBGL_compressed_texture_pvrtc;
+        ext = WEBGL_compressed_texture_pvrtc;
     }
     else if (aName.Equals(NS_LITERAL_STRING("MOZ_WEBGL_depth_texture"),
              nsCaseInsensitiveStringComparator()))
     {
-        if (IsExtensionSupported(WEBGL_depth_texture))
-            ext = WEBGL_depth_texture;
+        ext = WEBGL_depth_texture;
     }
 
     if (ext == WebGLExtensionID_unknown_extension) {
       return nullptr;
     }
 
-    if (!mExtensions[ext]) {
+    // step 2: check if the extension is supported
+    if (!IsExtensionSupported(ext)) {
+        return nullptr;
+    }
+
+    // step 3: if the extension hadn't been previously been created, create it now, thus enabling it
+    if (!IsExtensionEnabled(ext)) {
+        WebGLExtensionBase *obj = nullptr;
         switch (ext) {
             case OES_standard_derivatives:
-                mExtensions[ext] = new WebGLExtensionStandardDerivatives(this);
+                obj = new WebGLExtensionStandardDerivatives(this);
                 break;
             case EXT_texture_filter_anisotropic:
-                mExtensions[ext] = new WebGLExtensionTextureFilterAnisotropic(this);
+                obj = new WebGLExtensionTextureFilterAnisotropic(this);
                 break;
             case WEBGL_lose_context:
-                mExtensions[ext] = new WebGLExtensionLoseContext(this);
+                obj = new WebGLExtensionLoseContext(this);
                 break;
             case WEBGL_compressed_texture_s3tc:
-                mExtensions[ext] = new WebGLExtensionCompressedTextureS3TC(this);
+                obj = new WebGLExtensionCompressedTextureS3TC(this);
                 break;
             case WEBGL_compressed_texture_atc:
-                mExtensions[ext] = new WebGLExtensionCompressedTextureATC(this);
+                obj = new WebGLExtensionCompressedTextureATC(this);
                 break;
             case WEBGL_compressed_texture_pvrtc:
-                mExtensions[ext] = new WebGLExtensionCompressedTexturePVRTC(this);
+                obj = new WebGLExtensionCompressedTexturePVRTC(this);
                 break;
             case WEBGL_depth_texture:
-                mExtensions[ext] = new WebGLExtensionDepthTexture(this);
+                obj = new WebGLExtensionDepthTexture(this);
+                break;
+            case OES_texture_float:
+                obj = new WebGLExtensionTextureFloat(this);
                 break;
             default:
-                // create a generic WebGLExtension object for any extensions that don't
-                // have any additional tokens or methods. We still need these to be separate
-                // objects in case the user might extend the corresponding JS objects with custom
-                // properties.
-                mExtensions[ext] = new WebGLExtension(this);
-                break;
+                MOZ_ASSERT(false, "should not get there.");
         }
+        mExtensions.EnsureLengthAtLeast(ext + 1);
+        mExtensions[ext] = obj;
     }
 
-    return mExtensions[ext];
+    // step 4: return the extension as a JS object
+    JS::Value v;
+    JSObject* wrapper = GetWrapper();
+    JSAutoCompartment ac(cx, wrapper);
+    if (!WrapNewBindingObject(cx, wrapper, mExtensions[ext], &v)) {
+        return nullptr;
+    }
+    return &v.toObject();
 }
 
 void
 WebGLContext::ForceClearFramebufferWithDefaultValues(uint32_t mask, const nsIntRect& viewportRect)
 {
     MakeContextCurrent();
 
     bool initializeColorBuffer = 0 != (mask & LOCAL_GL_COLOR_BUFFER_BIT);
@@ -1502,32 +1515,16 @@ NS_IMETHODIMP base::SetName(WebGLuint aN
 
 NAME_NOT_SUPPORTED(WebGLTexture)
 NAME_NOT_SUPPORTED(WebGLBuffer)
 NAME_NOT_SUPPORTED(WebGLProgram)
 NAME_NOT_SUPPORTED(WebGLShader)
 NAME_NOT_SUPPORTED(WebGLFramebuffer)
 NAME_NOT_SUPPORTED(WebGLRenderbuffer)
 
-// WebGLExtension
-
-NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE_0(WebGLExtension)
-  
-NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(WebGLExtension)
-  NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
-  NS_INTERFACE_MAP_ENTRY(nsISupports)
-  NS_INTERFACE_MAP_ENTRY(nsIWebGLExtension)
-  NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(WebGLExtension)
-NS_INTERFACE_MAP_END 
-
-NS_IMPL_CYCLE_COLLECTING_ADDREF(WebGLExtension)
-NS_IMPL_CYCLE_COLLECTING_RELEASE(WebGLExtension)
-
-DOMCI_DATA(WebGLExtension, WebGLExtension)
-
 /* readonly attribute WebGLint size; */
 NS_IMETHODIMP
 WebGLActiveInfo::GetSize(WebGLint *aSize)
 {
     *aSize = mSize;
     return NS_OK;
 }
 
--- a/content/canvas/src/WebGLContext.h
+++ b/content/canvas/src/WebGLContext.h
@@ -67,24 +67,24 @@ namespace mozilla {
 
 class WebGLTexture;
 class WebGLBuffer;
 class WebGLProgram;
 class WebGLShader;
 class WebGLFramebuffer;
 class WebGLRenderbuffer;
 class WebGLUniformLocation;
-class WebGLExtension;
 class WebGLContext;
 struct WebGLVertexAttribData;
 class WebGLMemoryPressureObserver;
 class WebGLRectangleObject;
 class WebGLContextBoundObject;
 class WebGLActiveInfo;
 class WebGLShaderPrecisionFormat;
+class WebGLExtensionBase;
 
 enum FakeBlackStatus { DoNotNeedFakeBlack, DoNeedFakeBlack, DontKnowIfNeedFakeBlack };
 
 struct VertexAttrib0Status {
     enum { Default, EmulatedUninitializedArray, EmulatedInitializedArray };
 };
 
 struct BackbufferClearingStatus {
@@ -626,17 +626,17 @@ public:
         if (!IsContextStable())
             return 0;
         return mHeight;
     }
         
     JSObject *GetContextAttributes(ErrorResult &rv);
     bool IsContextLost() const { return !IsContextStable(); }
     void GetSupportedExtensions(dom::Nullable< nsTArray<nsString> > &retval);
-    nsIWebGLExtension* GetExtension(const nsAString& aName);
+    JSObject* GetExtension(JSContext* ctx, const nsAString& aName);
     void ActiveTexture(WebGLenum texture);
     void AttachShader(WebGLProgram* program, WebGLShader* shader);
     void BindAttribLocation(WebGLProgram* program, WebGLuint location,
                             const nsAString& name);
     void BindBuffer(WebGLenum target, WebGLBuffer* buf);
     void BindFramebuffer(WebGLenum target, WebGLFramebuffer* wfb);
     void BindRenderbuffer(WebGLenum target, WebGLRenderbuffer* wrb);
     void BindTexture(WebGLenum target, WebGLTexture *tex);
@@ -1170,25 +1170,22 @@ protected:
         OES_texture_float,
         OES_standard_derivatives,
         EXT_texture_filter_anisotropic,
         WEBGL_lose_context,
         WEBGL_compressed_texture_s3tc,
         WEBGL_compressed_texture_atc,
         WEBGL_compressed_texture_pvrtc,
         WEBGL_depth_texture,
-        WebGLExtensionID_number_of_extensions,
         WebGLExtensionID_unknown_extension
     };
-    nsAutoTArray<nsRefPtr<WebGLExtension>, WebGLExtensionID_number_of_extensions> mExtensions;
+    nsTArray<nsRefPtr<WebGLExtensionBase> > mExtensions;
 
     // returns true if the extension has been enabled by calling getExtension.
-    bool IsExtensionEnabled(WebGLExtensionID ext) {
-        return mExtensions[ext];
-    }
+    bool IsExtensionEnabled(WebGLExtensionID ext);
 
     // returns true if the extension is supported (as returned by getSupportedExtensions)
     bool IsExtensionSupported(WebGLExtensionID ext);
 
     nsTArray<WebGLenum> mCompressedTextureFormats;
 
     bool InitAndValidateGL();
     bool ValidateBuffers(int32_t *maxAllowedCount, const char *info);
@@ -1415,16 +1412,23 @@ public:
     friend class WebGLFramebuffer;
     friend class WebGLRenderbuffer;
     friend class WebGLProgram;
     friend class WebGLBuffer;
     friend class WebGLShader;
     friend class WebGLUniformLocation;
 };
 
+// used by DOM bindings in conjunction with GetParentObject
+inline nsISupports*
+ToSupports(WebGLContext* context)
+{
+  return static_cast<nsICanvasRenderingContextInternal*>(context);
+}
+
 // This class is a mixin for objects that are tied to a specific
 // context (which is to say, all of them).  They provide initialization
 // as well as comparison with the current context.
 class WebGLContextBoundObject
 {
 public:
     WebGLContextBoundObject(WebGLContext *context) {
         mContext = context;
@@ -3090,33 +3094,16 @@ public:
     }
 
 protected:
     WebGLint mRangeMin;
     WebGLint mRangeMax;
     WebGLint mPrecision;
 };
 
-class WebGLExtension
-    : public nsIWebGLExtension
-    , public WebGLContextBoundObject
-    , public nsWrapperCache
-{
-public:
-    WebGLExtension(WebGLContext *baseContext)
-        : WebGLContextBoundObject(baseContext)
-    {}
-
-    NS_DECL_CYCLE_COLLECTING_ISUPPORTS
-    NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(WebGLExtension)
-    NS_DECL_NSIWEBGLEXTENSION
-
-    virtual ~WebGLExtension() {}
-};
-
 inline const WebGLRectangleObject *WebGLContext::FramebufferRectangleObject() const {
     return mBoundFramebuffer ? mBoundFramebuffer->RectangleObject()
                              : static_cast<const WebGLRectangleObject*>(this);
 }
 
 /**
  ** Template implementations
  **/
--- a/content/canvas/src/WebGLContextGL.cpp
+++ b/content/canvas/src/WebGLContextGL.cpp
@@ -1718,17 +1718,17 @@ WebGLContext::GenerateMipmap(WebGLenum t
 
     if (!tex->IsFirstImagePowerOfTwo())
         return ErrorInvalidOperation("generateMipmap: Level zero of texture does not have power-of-two width and height.");
 
     GLenum format = tex->ImageInfoAt(0, 0).Format();
     if (IsTextureFormatCompressed(format))
         return ErrorInvalidOperation("generateMipmap: Texture data at level zero is compressed.");
 
-    if (IsExtensionEnabled(WEBGL_depth_texture) && 
+    if (IsExtensionEnabled(WEBGL_depth_texture) &&
         (format == LOCAL_GL_DEPTH_COMPONENT || format == LOCAL_GL_DEPTH_STENCIL))
         return ErrorInvalidOperation("generateMipmap: "
                                      "A texture that has a base internal format of "
                                      "DEPTH_COMPONENT or DEPTH_STENCIL isn't supported");
 
     if (!tex->AreAllLevel0ImageInfosEqual())
         return ErrorInvalidOperation("generateMipmap: The six faces of this cube map have different dimensions, format, or type.");
 
@@ -2664,17 +2664,16 @@ WebGLContext::GetTexParameter(WebGLenum 
         }
         case LOCAL_GL_TEXTURE_MAX_ANISOTROPY_EXT:
             if (IsExtensionEnabled(EXT_texture_filter_anisotropic)) {
                 GLfloat f = 0.f;
                 gl->fGetTexParameterfv(target, pname, &f);
                 return JS::DoubleValue(f);
             }
 
-            
             ErrorInvalidEnumInfo("getTexParameter: parameter", pname);
             break;
 
         default:
             ErrorInvalidEnumInfo("getTexParameter: parameter", pname);
     }
 
     return JS::NullValue();
@@ -4870,17 +4869,17 @@ WebGLContext::TexSubImage2D_base(WebGLen
     }
 
     if (level >= 1) {
         if (!(is_pot_assuming_nonnegative(width) &&
               is_pot_assuming_nonnegative(height)))
             return ErrorInvalidValue("texSubImage2D: with level > 0, width and height must be powers of two");
     }
 
-    if (IsExtensionEnabled(WEBGL_depth_texture) && 
+    if (IsExtensionEnabled(WEBGL_depth_texture) &&
         (format == LOCAL_GL_DEPTH_COMPONENT || format == LOCAL_GL_DEPTH_STENCIL)) {
         return ErrorInvalidOperation("texSubImage2D: format");
     }
 
     uint32_t dstTexelSize = 0;
     if (!ValidateTexFormatAndType(format, type, jsArrayType, &dstTexelSize, "texSubImage2D"))
         return;
 
new file mode 100644
--- /dev/null
+++ b/content/canvas/src/WebGLExtensionBase.cpp
@@ -0,0 +1,29 @@
+/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "WebGLContext.h"
+#include "WebGLExtensions.h"
+
+using namespace mozilla;
+
+WebGLExtensionBase::WebGLExtensionBase(WebGLContext* context)
+    : WebGLContextBoundObject(context)
+{
+    SetIsDOMBinding();
+}
+
+WebGLExtensionBase::~WebGLExtensionBase()
+{
+}
+
+NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE_0(WebGLExtensionBase)
+
+NS_IMPL_CYCLE_COLLECTING_ADDREF(WebGLExtensionBase)
+NS_IMPL_CYCLE_COLLECTING_RELEASE(WebGLExtensionBase)
+
+NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(WebGLExtensionBase)
+  NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
+  NS_INTERFACE_MAP_ENTRY(nsISupports)
+NS_INTERFACE_MAP_END
--- a/content/canvas/src/WebGLExtensionCompressedTextureATC.cpp
+++ b/content/canvas/src/WebGLExtensionCompressedTextureATC.cpp
@@ -1,32 +1,23 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this file,
  * You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "WebGLContext.h"
 #include "WebGLExtensions.h"
+#include "mozilla/dom/WebGLRenderingContextBinding.h"
 
 using namespace mozilla;
 
 WebGLExtensionCompressedTextureATC::WebGLExtensionCompressedTextureATC(WebGLContext* context)
-    : WebGLExtension(context)
+    : WebGLExtensionBase(context)
 {
     context->mCompressedTextureFormats.AppendElement(LOCAL_GL_ATC_RGB);
     context->mCompressedTextureFormats.AppendElement(LOCAL_GL_ATC_RGBA_EXPLICIT_ALPHA);
     context->mCompressedTextureFormats.AppendElement(LOCAL_GL_ATC_RGBA_INTERPOLATED_ALPHA);
 }
 
 WebGLExtensionCompressedTextureATC::~WebGLExtensionCompressedTextureATC()
 {
-
 }
 
-NS_IMPL_ADDREF_INHERITED(WebGLExtensionCompressedTextureATC, WebGLExtension)
-NS_IMPL_RELEASE_INHERITED(WebGLExtensionCompressedTextureATC, WebGLExtension)
-
-DOMCI_DATA(WebGLExtensionCompressedTextureATC, WebGLExtensionCompressedTextureATC)
-
-NS_INTERFACE_MAP_BEGIN(WebGLExtensionCompressedTextureATC)
-  NS_INTERFACE_MAP_ENTRY(nsIWebGLExtensionCompressedTextureATC)
-  NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, WebGLExtension)
-  NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(WebGLExtensionCompressedTextureATC)
-NS_INTERFACE_MAP_END_INHERITING(WebGLExtension)
+IMPL_WEBGL_EXTENSION_GOOP(WebGLExtensionCompressedTextureATC)
--- a/content/canvas/src/WebGLExtensionCompressedTexturePVRTC.cpp
+++ b/content/canvas/src/WebGLExtensionCompressedTexturePVRTC.cpp
@@ -1,33 +1,24 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this file,
  * You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "WebGLContext.h"
 #include "WebGLExtensions.h"
+#include "mozilla/dom/WebGLRenderingContextBinding.h"
 
 using namespace mozilla;
 
 WebGLExtensionCompressedTexturePVRTC::WebGLExtensionCompressedTexturePVRTC(WebGLContext* context)
-    : WebGLExtension(context)
+    : WebGLExtensionBase(context)
 {
     context->mCompressedTextureFormats.AppendElement(LOCAL_GL_COMPRESSED_RGB_PVRTC_4BPPV1);
     context->mCompressedTextureFormats.AppendElement(LOCAL_GL_COMPRESSED_RGB_PVRTC_2BPPV1);
     context->mCompressedTextureFormats.AppendElement(LOCAL_GL_COMPRESSED_RGBA_PVRTC_4BPPV1);
     context->mCompressedTextureFormats.AppendElement(LOCAL_GL_COMPRESSED_RGBA_PVRTC_2BPPV1);
 }
 
 WebGLExtensionCompressedTexturePVRTC::~WebGLExtensionCompressedTexturePVRTC()
 {
-
 }
 
-NS_IMPL_ADDREF_INHERITED(WebGLExtensionCompressedTexturePVRTC, WebGLExtension)
-NS_IMPL_RELEASE_INHERITED(WebGLExtensionCompressedTexturePVRTC, WebGLExtension)
-
-DOMCI_DATA(WebGLExtensionCompressedTexturePVRTC, WebGLExtensionCompressedTexturePVRTC)
-
-NS_INTERFACE_MAP_BEGIN(WebGLExtensionCompressedTexturePVRTC)
-  NS_INTERFACE_MAP_ENTRY(nsIWebGLExtensionCompressedTexturePVRTC)
-  NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, WebGLExtension)
-  NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(WebGLExtensionCompressedTexturePVRTC)
-NS_INTERFACE_MAP_END_INHERITING(WebGLExtension)
+IMPL_WEBGL_EXTENSION_GOOP(WebGLExtensionCompressedTexturePVRTC)
--- a/content/canvas/src/WebGLExtensionCompressedTextureS3TC.cpp
+++ b/content/canvas/src/WebGLExtensionCompressedTextureS3TC.cpp
@@ -1,33 +1,24 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this file,
  * You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "WebGLContext.h"
 #include "WebGLExtensions.h"
+#include "mozilla/dom/WebGLRenderingContextBinding.h"
 
 using namespace mozilla;
 
 WebGLExtensionCompressedTextureS3TC::WebGLExtensionCompressedTextureS3TC(WebGLContext* context)
-    : WebGLExtension(context)
+    : WebGLExtensionBase(context)
 {
     context->mCompressedTextureFormats.AppendElement(LOCAL_GL_COMPRESSED_RGB_S3TC_DXT1_EXT);
     context->mCompressedTextureFormats.AppendElement(LOCAL_GL_COMPRESSED_RGBA_S3TC_DXT1_EXT);
     context->mCompressedTextureFormats.AppendElement(LOCAL_GL_COMPRESSED_RGBA_S3TC_DXT3_EXT);
     context->mCompressedTextureFormats.AppendElement(LOCAL_GL_COMPRESSED_RGBA_S3TC_DXT5_EXT);
 }
 
 WebGLExtensionCompressedTextureS3TC::~WebGLExtensionCompressedTextureS3TC()
 {
-
 }
 
-NS_IMPL_ADDREF_INHERITED(WebGLExtensionCompressedTextureS3TC, WebGLExtension)
-NS_IMPL_RELEASE_INHERITED(WebGLExtensionCompressedTextureS3TC, WebGLExtension)
-
-DOMCI_DATA(WebGLExtensionCompressedTextureS3TC, WebGLExtensionCompressedTextureS3TC)
-
-NS_INTERFACE_MAP_BEGIN(WebGLExtensionCompressedTextureS3TC)
-  NS_INTERFACE_MAP_ENTRY(nsIWebGLExtensionCompressedTextureS3TC)
-  NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, WebGLExtension)
-  NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(WebGLExtensionCompressedTextureS3TC)
-NS_INTERFACE_MAP_END_INHERITING(WebGLExtension)
+IMPL_WEBGL_EXTENSION_GOOP(WebGLExtensionCompressedTextureS3TC)
--- a/content/canvas/src/WebGLExtensionDepthTexture.cpp
+++ b/content/canvas/src/WebGLExtensionDepthTexture.cpp
@@ -1,32 +1,21 @@
 /* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "WebGLContext.h"
 #include "WebGLExtensions.h"
+#include "mozilla/dom/WebGLRenderingContextBinding.h"
 
 using namespace mozilla;
 
-WebGLExtensionDepthTexture::WebGLExtensionDepthTexture(WebGLContext* context) :
-    WebGLExtension(context)
+WebGLExtensionDepthTexture::WebGLExtensionDepthTexture(WebGLContext* context)
+    : WebGLExtensionBase(context)
 {
-
 }
 
 WebGLExtensionDepthTexture::~WebGLExtensionDepthTexture()
 {
-
 }
 
-NS_IMPL_ADDREF_INHERITED(WebGLExtensionDepthTexture, WebGLExtension)
-NS_IMPL_RELEASE_INHERITED(WebGLExtensionDepthTexture, WebGLExtension)
-
-DOMCI_DATA(WebGLExtensionDepthTexture, WebGLExtensionDepthTexture)
-
-NS_INTERFACE_MAP_BEGIN(WebGLExtensionDepthTexture)
-  NS_INTERFACE_MAP_ENTRY(nsIWebGLExtensionDepthTexture)
-  NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, WebGLExtension)
-  NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(WebGLExtensionDepthTexture)
-NS_INTERFACE_MAP_END_INHERITING(WebGLExtension)
-
+IMPL_WEBGL_EXTENSION_GOOP(WebGLExtensionDepthTexture)
--- a/content/canvas/src/WebGLExtensionLoseContext.cpp
+++ b/content/canvas/src/WebGLExtensionLoseContext.cpp
@@ -1,49 +1,35 @@
 /* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "WebGLContext.h"
 #include "WebGLExtensions.h"
+#include "mozilla/dom/WebGLRenderingContextBinding.h"
 
 using namespace mozilla;
 
-WebGLExtensionLoseContext::WebGLExtensionLoseContext(WebGLContext* context) :
-    WebGLExtension(context)
+WebGLExtensionLoseContext::WebGLExtensionLoseContext(WebGLContext* context)
+    : WebGLExtensionBase(context)
 {
-
 }
 
 WebGLExtensionLoseContext::~WebGLExtensionLoseContext()
 {
-
 }
 
-NS_IMETHODIMP 
+void
 WebGLExtensionLoseContext::LoseContext()
 {
     if (!mContext->LoseContext())
         mContext->mWebGLError = LOCAL_GL_INVALID_OPERATION;
-
-    return NS_OK;
 }
 
-NS_IMETHODIMP 
+void 
 WebGLExtensionLoseContext::RestoreContext()
 {
     if (!mContext->RestoreContext())
         mContext->mWebGLError = LOCAL_GL_INVALID_OPERATION;
-
-    return NS_OK;
 }
 
-NS_IMPL_ADDREF_INHERITED(WebGLExtensionLoseContext, WebGLExtension)
-NS_IMPL_RELEASE_INHERITED(WebGLExtensionLoseContext, WebGLExtension)
-
-DOMCI_DATA(WebGLExtensionLoseContext, WebGLExtensionLoseContext)
-
-NS_INTERFACE_MAP_BEGIN(WebGLExtensionLoseContext)
-  NS_INTERFACE_MAP_ENTRY(nsIWebGLExtensionLoseContext)
-  NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, WebGLExtension)
-  NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(WebGLExtensionLoseContext)
-NS_INTERFACE_MAP_END_INHERITING(WebGLExtension)
+IMPL_WEBGL_EXTENSION_GOOP(WebGLExtensionLoseContext)
--- a/content/canvas/src/WebGLExtensionStandardDerivatives.cpp
+++ b/content/canvas/src/WebGLExtensionStandardDerivatives.cpp
@@ -1,31 +1,21 @@
 /* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "WebGLContext.h"
 #include "WebGLExtensions.h"
+#include "mozilla/dom/WebGLRenderingContextBinding.h"
 
 using namespace mozilla;
 
-WebGLExtensionStandardDerivatives::WebGLExtensionStandardDerivatives(WebGLContext* context) :
-    WebGLExtension(context)
+WebGLExtensionStandardDerivatives::WebGLExtensionStandardDerivatives(WebGLContext* context)
+    : WebGLExtensionBase(context)
 {
-
 }
 
 WebGLExtensionStandardDerivatives::~WebGLExtensionStandardDerivatives()
 {
-
 }
 
-NS_IMPL_ADDREF_INHERITED(WebGLExtensionStandardDerivatives, WebGLExtension)
-NS_IMPL_RELEASE_INHERITED(WebGLExtensionStandardDerivatives, WebGLExtension)
-
-DOMCI_DATA(WebGLExtensionStandardDerivatives, WebGLExtensionStandardDerivatives)
-
-NS_INTERFACE_MAP_BEGIN(WebGLExtensionStandardDerivatives)
-  NS_INTERFACE_MAP_ENTRY(nsIWebGLExtensionStandardDerivatives)
-  NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, WebGLExtension)
-  NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(WebGLExtensionStandardDerivatives)
-NS_INTERFACE_MAP_END_INHERITING(WebGLExtension)
+IMPL_WEBGL_EXTENSION_GOOP(WebGLExtensionStandardDerivatives)
--- a/content/canvas/src/WebGLExtensionTextureFilterAnisotropic.cpp
+++ b/content/canvas/src/WebGLExtensionTextureFilterAnisotropic.cpp
@@ -1,31 +1,21 @@
 /* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "WebGLContext.h"
 #include "WebGLExtensions.h"
+#include "mozilla/dom/WebGLRenderingContextBinding.h"
 
 using namespace mozilla;
 
-WebGLExtensionTextureFilterAnisotropic::WebGLExtensionTextureFilterAnisotropic(WebGLContext* context) :
-    WebGLExtension(context)
+WebGLExtensionTextureFilterAnisotropic::WebGLExtensionTextureFilterAnisotropic(WebGLContext* context)
+    : WebGLExtensionBase(context)
 {
-
 }
 
 WebGLExtensionTextureFilterAnisotropic::~WebGLExtensionTextureFilterAnisotropic()
 {
-
 }
 
-NS_IMPL_ADDREF_INHERITED(WebGLExtensionTextureFilterAnisotropic, WebGLExtension)
-NS_IMPL_RELEASE_INHERITED(WebGLExtensionTextureFilterAnisotropic, WebGLExtension)
-
-DOMCI_DATA(WebGLExtensionTextureFilterAnisotropic, WebGLExtensionTextureFilterAnisotropic)
-
-NS_INTERFACE_MAP_BEGIN(WebGLExtensionTextureFilterAnisotropic)
-  NS_INTERFACE_MAP_ENTRY(nsIWebGLExtensionTextureFilterAnisotropic)
-  NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, WebGLExtension)
-  NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(WebGLExtensionTextureFilterAnisotropic)
-NS_INTERFACE_MAP_END_INHERITING(WebGLExtension)
+IMPL_WEBGL_EXTENSION_GOOP(WebGLExtensionTextureFilterAnisotropic)
new file mode 100644
--- /dev/null
+++ b/content/canvas/src/WebGLExtensionTextureFloat.cpp
@@ -0,0 +1,20 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this file,
+ * You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "WebGLContext.h"
+#include "WebGLExtensions.h"
+#include "mozilla/dom/WebGLRenderingContextBinding.h"
+
+using namespace mozilla;
+
+WebGLExtensionTextureFloat::WebGLExtensionTextureFloat(WebGLContext* context)
+    : WebGLExtensionBase(context)
+{
+}
+
+WebGLExtensionTextureFloat::~WebGLExtensionTextureFloat()
+{
+}
+
+IMPL_WEBGL_EXTENSION_GOOP(WebGLExtensionTextureFloat)
--- a/content/canvas/src/WebGLExtensions.h
+++ b/content/canvas/src/WebGLExtensions.h
@@ -1,97 +1,124 @@
 /* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef WEBGLEXTENSIONS_H_
 #define WEBGLEXTENSIONS_H_
 
+#include "WebGLContext.h"
+
 namespace mozilla {
 
-class WebGLExtensionLoseContext :
-    public nsIWebGLExtensionLoseContext,
-    public WebGLExtension
+class WebGLExtensionBase
+    : public nsISupports
+    , public WebGLContextBoundObject
+    , public nsWrapperCache
+{
+public:
+    WebGLExtensionBase(WebGLContext*);
+    virtual ~WebGLExtensionBase();
+
+    WebGLContext *GetParentObject() const {
+        return Context();
+    }
+
+    NS_DECL_CYCLE_COLLECTING_ISUPPORTS
+    NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(WebGLExtensionBase)
+};
+
+#define DECL_WEBGL_EXTENSION_GOOP \
+    JSObject* WrapObject(JSContext *cx, JSObject *scope, bool *triedToWrap);
+
+#define IMPL_WEBGL_EXTENSION_GOOP(WebGLExtensionType) \
+    JSObject* \
+    WebGLExtensionType::WrapObject(JSContext *cx, JSObject *scope, bool *triedToWrap) { \
+        return dom::WebGLExtensionType##Binding::Wrap(cx, scope, this, triedToWrap); \
+    }
+
+class WebGLExtensionCompressedTextureATC
+    : public WebGLExtensionBase
+{
+public:
+    WebGLExtensionCompressedTextureATC(WebGLContext*);
+    virtual ~WebGLExtensionCompressedTextureATC();
+
+    DECL_WEBGL_EXTENSION_GOOP
+};
+
+class WebGLExtensionCompressedTexturePVRTC
+    : public WebGLExtensionBase
+{
+public:
+    WebGLExtensionCompressedTexturePVRTC(WebGLContext*);
+    virtual ~WebGLExtensionCompressedTexturePVRTC();
+
+    DECL_WEBGL_EXTENSION_GOOP
+};
+
+class WebGLExtensionCompressedTextureS3TC
+    : public WebGLExtensionBase
+{
+public:
+    WebGLExtensionCompressedTextureS3TC(WebGLContext*);
+    virtual ~WebGLExtensionCompressedTextureS3TC();
+
+    DECL_WEBGL_EXTENSION_GOOP
+};
+
+class WebGLExtensionDepthTexture
+    : public WebGLExtensionBase
+{
+public:
+    WebGLExtensionDepthTexture(WebGLContext*);
+    virtual ~WebGLExtensionDepthTexture();
+
+    DECL_WEBGL_EXTENSION_GOOP
+};
+
+class WebGLExtensionLoseContext
+    : public WebGLExtensionBase
 {
 public:
     WebGLExtensionLoseContext(WebGLContext*);
     virtual ~WebGLExtensionLoseContext();
 
-    NS_DECL_ISUPPORTS_INHERITED
-    NS_DECL_NSIWEBGLEXTENSIONLOSECONTEXT
-};
+    void LoseContext();
+    void RestoreContext();
 
-class WebGLExtensionStandardDerivatives :
-    public nsIWebGLExtensionStandardDerivatives,
-    public WebGLExtension
-{
-public:
-    WebGLExtensionStandardDerivatives(WebGLContext* context);
-    virtual ~WebGLExtensionStandardDerivatives();
-
-    NS_DECL_ISUPPORTS_INHERITED
-    NS_DECL_NSIWEBGLEXTENSION
+    DECL_WEBGL_EXTENSION_GOOP
 };
 
-class WebGLExtensionTextureFilterAnisotropic :
-    public nsIWebGLExtensionTextureFilterAnisotropic,
-    public WebGLExtension
+class WebGLExtensionStandardDerivatives
+    : public WebGLExtensionBase
 {
 public:
-    WebGLExtensionTextureFilterAnisotropic(WebGLContext* context);
-    virtual ~WebGLExtensionTextureFilterAnisotropic();
-
-    NS_DECL_ISUPPORTS_INHERITED
-    NS_DECL_NSIWEBGLEXTENSION
-};
+    WebGLExtensionStandardDerivatives(WebGLContext*);
+    virtual ~WebGLExtensionStandardDerivatives();
 
-class WebGLExtensionCompressedTextureS3TC :
-    public nsIWebGLExtensionCompressedTextureS3TC,
-    public WebGLExtension
-{
-public:
-    WebGLExtensionCompressedTextureS3TC(WebGLContext* context);
-    virtual ~WebGLExtensionCompressedTextureS3TC();
-
-    NS_DECL_ISUPPORTS_INHERITED
-    NS_DECL_NSIWEBGLEXTENSION
+    DECL_WEBGL_EXTENSION_GOOP
 };
 
-class WebGLExtensionCompressedTextureATC :
-    public nsIWebGLExtensionCompressedTextureATC,
-    public WebGLExtension
-{
-public:
-    WebGLExtensionCompressedTextureATC(WebGLContext* context);
-    virtual ~WebGLExtensionCompressedTextureATC();
-
-    NS_DECL_ISUPPORTS_INHERITED
-    NS_DECL_NSIWEBGLEXTENSION
-};
-
-class WebGLExtensionCompressedTexturePVRTC :
-    public nsIWebGLExtensionCompressedTexturePVRTC,
-    public WebGLExtension
+class WebGLExtensionTextureFilterAnisotropic
+    : public WebGLExtensionBase
 {
 public:
-    WebGLExtensionCompressedTexturePVRTC(WebGLContext* context);
-    virtual ~WebGLExtensionCompressedTexturePVRTC();
+    WebGLExtensionTextureFilterAnisotropic(WebGLContext*);
+    virtual ~WebGLExtensionTextureFilterAnisotropic();
 
-    NS_DECL_ISUPPORTS_INHERITED
-    NS_DECL_NSIWEBGLEXTENSION
+    DECL_WEBGL_EXTENSION_GOOP
 };
 
-class WebGLExtensionDepthTexture :
-    public nsIWebGLExtensionDepthTexture,
-    public WebGLExtension
+class WebGLExtensionTextureFloat
+    : public WebGLExtensionBase
 {
 public:
-    WebGLExtensionDepthTexture(WebGLContext* context);
-    virtual ~WebGLExtensionDepthTexture();
+    WebGLExtensionTextureFloat(WebGLContext*);
+    virtual ~WebGLExtensionTextureFloat();
 
-    NS_DECL_ISUPPORTS_INHERITED
-    NS_DECL_NSIWEBGLEXTENSION
+    DECL_WEBGL_EXTENSION_GOOP
 };
 
-}
+} // namespace mozilla
 
 #endif // WEBGLEXTENSIONS_H_
--- a/dom/base/nsDOMClassInfo.cpp
+++ b/dom/base/nsDOMClassInfo.cpp
@@ -1564,40 +1564,16 @@ static nsDOMClassInfoData sClassInfoData
   NS_DEFINE_CLASSINFO_DATA(WebGLShader, nsDOMGenericSH,
                            DOM_DEFAULT_SCRIPTABLE_FLAGS)
   NS_DEFINE_CLASSINFO_DATA(WebGLFramebuffer, nsDOMGenericSH,
                            DOM_DEFAULT_SCRIPTABLE_FLAGS)
   NS_DEFINE_CLASSINFO_DATA(WebGLRenderbuffer, nsDOMGenericSH,
                            DOM_DEFAULT_SCRIPTABLE_FLAGS)
   NS_DEFINE_CLASSINFO_DATA(WebGLActiveInfo, nsDOMGenericSH,
                            DOM_DEFAULT_SCRIPTABLE_FLAGS)
-  NS_DEFINE_CLASSINFO_DATA(WebGLExtension, WebGLExtensionSH,
-                           DOM_DEFAULT_SCRIPTABLE_FLAGS |
-                           nsIXPCScriptable::WANT_ADDPROPERTY)
-  NS_DEFINE_CLASSINFO_DATA(WebGLExtensionStandardDerivatives, WebGLExtensionSH,
-                           DOM_DEFAULT_SCRIPTABLE_FLAGS |
-                           nsIXPCScriptable::WANT_ADDPROPERTY)
-  NS_DEFINE_CLASSINFO_DATA(WebGLExtensionTextureFilterAnisotropic, WebGLExtensionSH,
-                           DOM_DEFAULT_SCRIPTABLE_FLAGS |
-                           nsIXPCScriptable::WANT_ADDPROPERTY)
-  NS_DEFINE_CLASSINFO_DATA(WebGLExtensionLoseContext, WebGLExtensionSH,
-                           DOM_DEFAULT_SCRIPTABLE_FLAGS |
-                           nsIXPCScriptable::WANT_ADDPROPERTY)
-  NS_DEFINE_CLASSINFO_DATA(WebGLExtensionCompressedTextureS3TC, WebGLExtensionSH,
-                           DOM_DEFAULT_SCRIPTABLE_FLAGS |
-                           nsIXPCScriptable::WANT_ADDPROPERTY)
-  NS_DEFINE_CLASSINFO_DATA(WebGLExtensionCompressedTextureATC, WebGLExtensionSH,
-                           DOM_DEFAULT_SCRIPTABLE_FLAGS |
-                           nsIXPCScriptable::WANT_ADDPROPERTY)
-  NS_DEFINE_CLASSINFO_DATA(WebGLExtensionCompressedTexturePVRTC, WebGLExtensionSH,
-                           DOM_DEFAULT_SCRIPTABLE_FLAGS |
-                           nsIXPCScriptable::WANT_ADDPROPERTY)
-  NS_DEFINE_CLASSINFO_DATA(WebGLExtensionDepthTexture, WebGLExtensionSH,
-                           DOM_DEFAULT_SCRIPTABLE_FLAGS |
-                           nsIXPCScriptable::WANT_ADDPROPERTY)
 
   NS_DEFINE_CLASSINFO_DATA(PaintRequest, nsDOMGenericSH,
                            DOM_DEFAULT_SCRIPTABLE_FLAGS)
   NS_DEFINE_CLASSINFO_DATA(PaintRequestList, nsDOMGenericSH,
                            DOM_DEFAULT_SCRIPTABLE_FLAGS)
 
   NS_DEFINE_CLASSINFO_DATA(ScrollAreaEvent, nsDOMGenericSH,
                            DOM_DEFAULT_SCRIPTABLE_FLAGS)
@@ -4254,48 +4230,16 @@ nsDOMClassInfo::Init()
   DOM_CLASSINFO_MAP_BEGIN(WebGLRenderbuffer, nsIWebGLRenderbuffer)
      DOM_CLASSINFO_MAP_ENTRY(nsIWebGLRenderbuffer)
   DOM_CLASSINFO_MAP_END
 
   DOM_CLASSINFO_MAP_BEGIN(WebGLActiveInfo, nsIWebGLActiveInfo)
     DOM_CLASSINFO_MAP_ENTRY(nsIWebGLActiveInfo)
   DOM_CLASSINFO_MAP_END
 
-  DOM_CLASSINFO_MAP_BEGIN(WebGLExtension, nsIWebGLExtension)
-    DOM_CLASSINFO_MAP_ENTRY(nsIWebGLExtension)
-  DOM_CLASSINFO_MAP_END
-  
-  DOM_CLASSINFO_MAP_BEGIN(WebGLExtensionStandardDerivatives, nsIWebGLExtensionStandardDerivatives)
-    DOM_CLASSINFO_MAP_ENTRY(nsIWebGLExtensionStandardDerivatives)
-  DOM_CLASSINFO_MAP_END
-  
-  DOM_CLASSINFO_MAP_BEGIN(WebGLExtensionTextureFilterAnisotropic, nsIWebGLExtensionTextureFilterAnisotropic)
-    DOM_CLASSINFO_MAP_ENTRY(nsIWebGLExtensionTextureFilterAnisotropic)
-  DOM_CLASSINFO_MAP_END
-
-  DOM_CLASSINFO_MAP_BEGIN(WebGLExtensionLoseContext, nsIWebGLExtensionLoseContext)
-    DOM_CLASSINFO_MAP_ENTRY(nsIWebGLExtensionLoseContext)
-  DOM_CLASSINFO_MAP_END
-
-  DOM_CLASSINFO_MAP_BEGIN(WebGLExtensionCompressedTextureS3TC, nsIWebGLExtensionCompressedTextureS3TC)
-    DOM_CLASSINFO_MAP_ENTRY(nsIWebGLExtensionCompressedTextureS3TC)
-  DOM_CLASSINFO_MAP_END
-
-  DOM_CLASSINFO_MAP_BEGIN(WebGLExtensionCompressedTextureATC, nsIWebGLExtensionCompressedTextureATC)
-    DOM_CLASSINFO_MAP_ENTRY(nsIWebGLExtensionCompressedTextureATC)
-  DOM_CLASSINFO_MAP_END
-
-  DOM_CLASSINFO_MAP_BEGIN(WebGLExtensionCompressedTexturePVRTC, nsIWebGLExtensionCompressedTexturePVRTC)
-    DOM_CLASSINFO_MAP_ENTRY(nsIWebGLExtensionCompressedTexturePVRTC)
-  DOM_CLASSINFO_MAP_END
-
-  DOM_CLASSINFO_MAP_BEGIN(WebGLExtensionDepthTexture, nsIWebGLExtensionDepthTexture)
-    DOM_CLASSINFO_MAP_ENTRY(nsIWebGLExtensionDepthTexture)
-  DOM_CLASSINFO_MAP_END
-
   DOM_CLASSINFO_MAP_BEGIN(PaintRequest, nsIDOMPaintRequest)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMPaintRequest)
    DOM_CLASSINFO_MAP_END
  
   DOM_CLASSINFO_MAP_BEGIN(PaintRequestList, nsIDOMPaintRequestList)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMPaintRequestList)
   DOM_CLASSINFO_MAP_END
 
@@ -10831,45 +10775,16 @@ nsSVGStringListSH::GetStringAt(nsISuppor
 #endif
   if (rv == NS_ERROR_DOM_INDEX_SIZE_ERR) {
     SetDOMStringToNull(aResult);
     rv = NS_OK;
   }
   return rv;
 }
 
-NS_IMETHODIMP
-WebGLExtensionSH::AddProperty(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
-                              JSObject *obj, jsid id, jsval *vp, bool *_retval)
-{
-  WebGLExtensionSH::PreserveWrapper(GetNative(wrapper, obj));
-
-  return NS_OK;
-}
-
-void
-WebGLExtensionSH::PreserveWrapper(nsISupports *aNative)
-{
-  WebGLExtension* ext = static_cast<WebGLExtension*>(aNative);
-  nsContentUtils::PreserveWrapper(aNative, ext);
-}
-
-nsresult
-WebGLExtensionSH::PreCreate(nsISupports *nativeObj, JSContext *cx,
-                            JSObject *globalObj, JSObject **parentObj)
-{
-  *parentObj = globalObj;
-
-  WebGLExtension *ext = static_cast<WebGLExtension*>(nativeObj);
-  WebGLContext *webgl = ext->Context();
-  nsINode *node = webgl->GetParentObject();
-
-  return WrapNativeParent(cx, globalObj, node, parentObj);
-}
-
 nsresult
 nsNewDOMBindingNoWrapperCacheSH::PreCreate(nsISupports *nativeObj,
                                            JSContext *cx,
                                            JSObject *globalObj,
                                            JSObject **parentObj)
 {
   // We don't allow this
   return NS_ERROR_UNEXPECTED;
--- a/dom/base/nsDOMClassInfo.h
+++ b/dom/base/nsDOMClassInfo.h
@@ -476,42 +476,16 @@ public:
                         JSObject **objp, bool *_retval);
 
   static nsIClassInfo *doCreate(nsDOMClassInfoData* aData)
   {
     return new nsNavigatorSH(aData);
   }
 };
 
-// WebGLExtension scriptable helper
-
-class WebGLExtensionSH : public nsDOMGenericSH
-{
-protected:
-  WebGLExtensionSH(nsDOMClassInfoData* aData) : nsDOMGenericSH(aData)
-  {
-  }
-
-  virtual ~WebGLExtensionSH()
-  {
-  }
-
-public:
-  NS_IMETHOD PreCreate(nsISupports *nativeObj, JSContext *cx,
-                       JSObject *globalObj, JSObject **parentObj);
-  NS_IMETHOD AddProperty(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
-                         JSObject *obj, jsid id, jsval *vp, bool *_retval);
-  virtual void PreserveWrapper(nsISupports *aNative);
-
-  static nsIClassInfo *doCreate(nsDOMClassInfoData* aData)
-  {
-    return new WebGLExtensionSH(aData);
-  }
-};
-
 // scriptable helper for new-binding objects without wrapper caches
 
 class nsNewDOMBindingNoWrapperCacheSH : public nsDOMGenericSH
 {
 protected:
   nsNewDOMBindingNoWrapperCacheSH(nsDOMClassInfoData* aData) : nsDOMGenericSH(aData)
   {
   }
--- a/dom/base/nsDOMClassInfoClasses.h
+++ b/dom/base/nsDOMClassInfoClasses.h
@@ -449,24 +449,16 @@ DOMCI_CLASS(MathMLElement)
 // WebGL
 DOMCI_CLASS(WebGLBuffer)
 DOMCI_CLASS(WebGLTexture)
 DOMCI_CLASS(WebGLProgram)
 DOMCI_CLASS(WebGLShader)
 DOMCI_CLASS(WebGLFramebuffer)
 DOMCI_CLASS(WebGLRenderbuffer)
 DOMCI_CLASS(WebGLActiveInfo)
-DOMCI_CLASS(WebGLExtension)
-DOMCI_CLASS(WebGLExtensionStandardDerivatives)
-DOMCI_CLASS(WebGLExtensionTextureFilterAnisotropic)
-DOMCI_CLASS(WebGLExtensionLoseContext)
-DOMCI_CLASS(WebGLExtensionCompressedTextureS3TC)
-DOMCI_CLASS(WebGLExtensionCompressedTextureATC)
-DOMCI_CLASS(WebGLExtensionCompressedTexturePVRTC)
-DOMCI_CLASS(WebGLExtensionDepthTexture)
 
 DOMCI_CLASS(PaintRequest)
 DOMCI_CLASS(PaintRequestList)
 
 DOMCI_CLASS(ScrollAreaEvent)
 
 DOMCI_CLASS(EventListenerInfo)
 
--- a/dom/bindings/Bindings.conf
+++ b/dom/bindings/Bindings.conf
@@ -337,32 +337,72 @@ DOMInterfaces = {
     'headerFile': 'mozilla/dom/TextEncoder.h',
     'implicitJSContext': [ 'encode' ],
 },
 
 'TextDecoder': {
     'headerFile': 'mozilla/dom/TextDecoder.h',
 },
 
+'WebGLExtensionCompressedTextureATC': {
+   'nativeType': 'mozilla::WebGLExtensionCompressedTextureATC',
+   'headerFile': 'WebGLExtensions.h'
+},
+
+'WebGLExtensionCompressedTexturePVRTC': {
+   'nativeType': 'mozilla::WebGLExtensionCompressedTexturePVRTC',
+   'headerFile': 'WebGLExtensions.h'
+},
+
+'WebGLExtensionCompressedTextureS3TC': {
+   'nativeType': 'mozilla::WebGLExtensionCompressedTextureS3TC',
+   'headerFile': 'WebGLExtensions.h'
+},
+
+'WebGLExtensionDepthTexture': {
+   'nativeType': 'mozilla::WebGLExtensionDepthTexture',
+   'headerFile': 'WebGLExtensions.h'
+},
+
+'WebGLExtensionLoseContext': {
+   'nativeType': 'mozilla::WebGLExtensionLoseContext',
+   'headerFile': 'WebGLExtensions.h'
+},
+
+'WebGLExtensionStandardDerivatives': {
+   'nativeType': 'mozilla::WebGLExtensionStandardDerivatives',
+   'headerFile': 'WebGLExtensions.h'
+},
+
+'WebGLExtensionTextureFilterAnisotropic': {
+   'nativeType': 'mozilla::WebGLExtensionTextureFilterAnisotropic',
+   'headerFile': 'WebGLExtensions.h'
+},
+
+'WebGLExtensionTextureFloat': {
+   'nativeType': 'mozilla::WebGLExtensionTextureFloat',
+   'headerFile': 'WebGLExtensions.h'
+},
+
 'WebGLRenderingContext': {
   'nativeType': 'mozilla::WebGLContext',
   'headerFile': 'WebGLContext.h',
   'resultNotAddRefed': [ 'canvas', 'getContextAttributes', 'getExtension',
                          'getAttachedShaders' ],
   'implicitJSContext': [ 'texImage2D', 'texSubImage2D' ],
 },
 
-'WebGLUniformLocation': {
-   'nativeType': 'mozilla::WebGLUniformLocation',
+'WebGLShaderPrecisionFormat': {
+   'nativeType': 'mozilla::WebGLShaderPrecisionFormat',
    'headerFile': 'WebGLContext.h',
    'wrapperCache': False
 },
 
-'WebGLShaderPrecisionFormat': {
-   'nativeType': 'mozilla::WebGLShaderPrecisionFormat',
+'WebGLUniformLocation': {
+   'nativeType': 'mozilla::WebGLUniformLocation',
    'headerFile': 'WebGLContext.h',
    'wrapperCache': False
 },
 
 'XMLHttpRequest': [
 {
     'nativeType': 'nsXMLHttpRequest',
     'implicitJSContext': [ 'constructor', ],
@@ -541,18 +581,16 @@ addExternalIface('SVGTransform')
 addExternalIface('TextMetrics', headerFile='nsIDOMCanvasRenderingContext2D.h')
 addExternalIface('Touch', headerFile='nsIDOMTouchEvent.h')
 addExternalIface('WebGLActiveInfo', nativeType='mozilla::WebGLActiveInfo',
                  headerFile='WebGLContext.h')
 addExternalIface('WebGLBuffer', nativeType='mozilla::WebGLBuffer',
                  headerFile='WebGLContext.h')
 addExternalIface('WebGLContextAttributes', nativeType='JSObject',
                  headerFile='jsapi.h')
-addExternalIface('WebGLExtension', nativeType='nsIWebGLExtension',
-                 headerFile='WebGLContext.h')
 addExternalIface('WebGLFramebuffer', nativeType='mozilla::WebGLFramebuffer',
                  headerFile='WebGLContext.h')
 addExternalIface('WebGLProgram', nativeType='mozilla::WebGLProgram',
                  headerFile='WebGLContext.h')
 addExternalIface('WebGLRenderbuffer', nativeType='mozilla::WebGLRenderbuffer',
                  headerFile='WebGLContext.h')
 addExternalIface('WebGLShader', nativeType='mozilla::WebGLShader',
                  headerFile='WebGLContext.h')
--- a/dom/webidl/WebGLRenderingContext.webidl
+++ b/dom/webidl/WebGLRenderingContext.webidl
@@ -4,18 +4,16 @@
  * You can obtain one at http://mozilla.org/MPL/2.0/.
  *
  * The origin of this IDL file is
  * https://www.khronos.org/registry/webgl/specs/latest/webgl.idl
  *
  * Copyright © 2012 Khronos Group
  */
 
- // AUTOGENERATED FILE -- DO NOT EDIT -- SEE Makefile
-//
 // WebGL IDL definitions scraped from the Khronos specification:
 // https://www.khronos.org/registry/webgl/specs/latest/
 //
 // This IDL depends on the typed array specification defined at:
 // https://www.khronos.org/registry/typedarray/specs/latest/typedarrays.idl
 
 // XXXbz all sorts of forward declarations for things that are not new
 // bindings yet.
@@ -46,18 +44,16 @@ typedef float          GLclampf;
     boolean alpha = true;
     boolean depth = true;
     boolean stencil = false;
     boolean antialias = true;
     boolean premultipliedAlpha = true;
     boolean preserveDrawingBuffer = false;
     };*/
 
-interface WebGLExtension;
-
 interface WebGLBuffer;
 
 interface WebGLFramebuffer;
 
 interface WebGLProgram;
 
 interface WebGLRenderbuffer;
 
@@ -495,22 +491,20 @@ interface WebGLRenderingContext {
 
     // The canvas might actually be null in some cases, apparently.
     readonly attribute HTMLCanvasElement? canvas;
     readonly attribute GLsizei drawingBufferWidth;
     readonly attribute GLsizei drawingBufferHeight;
 
     [WebGLHandlesContextLoss, Throws] WebGLContextAttributes getContextAttributes();
     [WebGLHandlesContextLoss] boolean isContextLost();
-    
+
     sequence<DOMString>? getSupportedExtensions();
 
-    // XXXbz In the spec, this is "object?"; I'm making it
-    // WebGLExtension? just for ease of implementation.
-    WebGLExtension? getExtension(DOMString name);
+    object? getExtension(DOMString name);
 
     void activeTexture(GLenum texture);
     void attachShader(WebGLProgram? program, WebGLShader? shader);
     void bindAttribLocation(WebGLProgram? program, GLuint index, DOMString name);
     void bindBuffer(GLenum target, WebGLBuffer? buffer);
     void bindFramebuffer(GLenum target, WebGLFramebuffer? framebuffer);
     void bindRenderbuffer(GLenum target, WebGLRenderbuffer? renderbuffer);
     void bindTexture(GLenum target, WebGLTexture? texture);
@@ -759,8 +753,58 @@ interface WebGLRenderingContext {
 interface WebGLContextEvent : Event {
     readonly attribute DOMString statusMessage;
     };*/
 
 // EventInit is defined in the DOM4 specification.
 /*dictionary WebGLContextEventInit : EventInit {
     DOMString statusMessage;
     };*/
+
+
+// specific extension interfaces
+
+interface WebGLExtensionStandardDerivatives {
+    const GLenum FRAGMENT_SHADER_DERIVATIVE_HINT_OES = 0x8B8B;
+};
+
+interface WebGLExtensionLoseContext {
+    void loseContext();
+    void restoreContext();
+};
+
+interface WebGLExtensionTextureFilterAnisotropic
+{
+    const GLenum TEXTURE_MAX_ANISOTROPY_EXT     = 0x84FE;
+    const GLenum MAX_TEXTURE_MAX_ANISOTROPY_EXT = 0x84FF;
+};
+
+interface WebGLExtensionCompressedTextureS3TC
+{
+    const GLenum COMPRESSED_RGB_S3TC_DXT1_EXT  = 0x83F0;
+    const GLenum COMPRESSED_RGBA_S3TC_DXT1_EXT = 0x83F1;
+    const GLenum COMPRESSED_RGBA_S3TC_DXT3_EXT = 0x83F2;
+    const GLenum COMPRESSED_RGBA_S3TC_DXT5_EXT = 0x83F3;
+};
+
+interface WebGLExtensionCompressedTextureATC
+{
+    const GLenum COMPRESSED_RGB_ATC_WEBGL                     = 0x8C92;
+    const GLenum COMPRESSED_RGBA_ATC_EXPLICIT_ALPHA_WEBGL     = 0x8C93;
+    const GLenum COMPRESSED_RGBA_ATC_INTERPOLATED_ALPHA_WEBGL = 0x87EE;
+};
+
+interface WebGLExtensionCompressedTexturePVRTC
+{
+    const GLenum COMPRESSED_RGB_PVRTC_4BPPV1  = 0x8C00;
+    const GLenum COMPRESSED_RGB_PVRTC_2BPPV1  = 0x8C01;
+    const GLenum COMPRESSED_RGBA_PVRTC_4BPPV1 = 0x8C02;
+    const GLenum COMPRESSED_RGBA_PVRTC_2BPPV1 = 0x8C03;
+};
+
+interface WebGLExtensionDepthTexture
+{
+    const GLenum UNSIGNED_INT_24_8_WEBGL = 0x84FA;
+};
+
+interface WebGLExtensionTextureFloat
+{
+};
--- a/js/xpconnect/src/dom_quickstubs.qsconf
+++ b/js/xpconnect/src/dom_quickstubs.qsconf
@@ -464,24 +464,16 @@ irregularFilenames = {
     'nsIWebGLTexture': 'nsIDOMWebGLRenderingContext',
     'nsIWebGLBuffer': 'nsIDOMWebGLRenderingContext',
     'nsIWebGLProgram': 'nsIDOMWebGLRenderingContext',
     'nsIWebGLShader': 'nsIDOMWebGLRenderingContext',
     'nsIWebGLShaderArray': 'nsIDOMWebGLRenderingContext',
     'nsIWebGLFramebuffer': 'nsIDOMWebGLRenderingContext',
     'nsIWebGLRenderbuffer': 'nsIDOMWebGLRenderingContext',
     'nsIWebGLActiveInfo': 'nsIDOMWebGLRenderingContext',
-    'nsIWebGLExtension': 'nsIDOMWebGLRenderingContext',
-    'nsIWebGLExtensionStandardDerivatives' : 'nsIDOMWebGLRenderingContext',
-    'nsIWebGLExtensionTextureFilterAnisotropic' : 'nsIDOMWebGLRenderingContext',
-    'nsIWebGLExtensionLoseContext' : 'nsIDOMWebGLRenderingContext',
-    'nsIWebGLExtensionCompressedTextureS3TC' : 'nsIDOMWebGLRenderingContext',
-    'nsIWebGLExtensionCompressedTextureATC' : 'nsIDOMWebGLRenderingContext',
-    'nsIWebGLExtensionCompressedTexturePVRTC' : 'nsIDOMWebGLRenderingContext',
-    'nsIWebGLExtensionDepthTexture' : 'nsIDOMWebGLRenderingContext',
 
     'nsIIndexedDatabaseUsageCallback': 'nsIIndexedDatabaseManager',
 
     'nsIDOMTouch': 'nsIDOMTouchEvent',
     'nsIDOMTouchList': 'nsIDOMTouchEvent',
 
     'nsIDOMMutationRecord': 'nsIDOMMutationObserver',