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 109234 0984909abb53f9513ed1dea302b840281958e3a4
parent 109233 ed26b7f1a02a685a43ad0db2ad8c9734a9d1e392
child 109235 a5a4c320de967082e9049a82d044d1aef40371cc
push id82
push usershu@rfrn.org
push dateFri, 05 Oct 2012 13:20:22 +0000
reviewersbz, jgilbert
bugs779611
milestone18.0a1
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',