Backed out changeset b35354fe21e3
authorRobert O'Callahan <robert@ocallahan.org>
Thu, 04 Mar 2010 14:38:00 +1300
changeset 38914 4f282c6200f258abe58e4d93337fdb7734c6ac50
parent 38907 b35354fe21e36934c937f71c26af780d07facf54
child 38915 0923645742e5cf559c6bd19634cbd60fc3711f21
push id11935
push userrocallahan@mozilla.com
push dateThu, 04 Mar 2010 01:38:44 +0000
treeherderautoland@0923645742e5 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
milestone1.9.3a3pre
backs outb35354fe21e36934c937f71c26af780d07facf54
Backed out changeset b35354fe21e3
content/canvas/src/Makefile.in
content/canvas/src/SimpleBuffer.cpp
content/canvas/src/SimpleBuffer.h
content/canvas/src/WebGLArrays.cpp
content/canvas/src/WebGLArrays.h
content/canvas/src/WebGLContext.cpp
content/canvas/src/WebGLContext.h
content/canvas/src/WebGLContextGL.cpp
content/canvas/src/localgl.h
dom/interfaces/canvas/nsICanvasRenderingContextGL.idl
dom/interfaces/canvas/nsICanvasRenderingContextGLBuffer.idl
dom/interfaces/canvas/nsICanvasRenderingContextGLWeb20.idl
--- a/content/canvas/src/Makefile.in
+++ b/content/canvas/src/Makefile.in
@@ -86,16 +86,17 @@ CPPSRCS += \
 	WebGLContext.cpp \
 	WebGLContextGL.cpp \
 	WebGLContextUtils.cpp \
 	WebGLContextValidate.cpp \
 	NativeJSContext.cpp \
 	glwrap.cpp \
 	nsGLPbuffer.cpp \
 	nsGLPbufferOSMesa.cpp \
+	SimpleBuffer.cpp \
 	$(NULL)
 
 CPPSRCS += nsGLPbuffer$(WEBGL_PLATFORM).cpp
 DEFINES += -DUSE_$(WEBGL_PLATFORM)
 
 else
 
 CPPSRCS += WebGLContextNotSupported.cpp
new file mode 100644
--- /dev/null
+++ b/content/canvas/src/SimpleBuffer.cpp
@@ -0,0 +1,144 @@
+/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is mozilla.org code.
+ *
+ * The Initial Developer of the Original Code is
+ *   Mozilla Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 2007
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   Vladimir Vukicevic <vladimir@pobox.com> (original author)
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include "SimpleBuffer.h"
+
+using namespace mozilla;
+
+#define FOO(_x,_y) JSBool _x (JSContext *cx, JSObject *obj, jsuint offset, jsuint count, _y *dest) { return 0; }
+
+FOO(js_ArrayToJSUint8Buffer, JSUint8)
+FOO(js_ArrayToJSUint16Buffer, JSUint16)
+FOO(js_ArrayToJSUint32Buffer, JSUint32)
+FOO(js_ArrayToJSInt8Buffer, JSInt8)
+FOO(js_ArrayToJSInt16Buffer, JSInt16)
+FOO(js_ArrayToJSInt32Buffer, JSInt32)
+FOO(js_ArrayToJSDoubleBuffer, jsdouble)
+
+PRBool
+SimpleBuffer::InitFromJSArray(PRUint32 typeParam,
+                              PRUint32 sizeParam,
+                              JSContext *ctx,
+                              JSObject *arrayObj,
+                              jsuint arrayLen)
+{
+    if (typeParam == LOCAL_GL_SHORT) {
+        Prepare(typeParam, sizeParam, arrayLen);
+        short *ptr = (short*) data;
+
+        if (!js_ArrayToJSInt16Buffer(ctx, arrayObj, 0, arrayLen, ptr)) {
+            for (PRUint32 i = 0; i < arrayLen; i++) {
+                jsval jv;
+                int32 iv;
+                ::JS_GetElement(ctx, arrayObj, i, &jv);
+                ::JS_ValueToECMAInt32(ctx, jv, &iv);
+                *ptr++ = (short) iv;
+            }
+        }
+    } else if (typeParam == LOCAL_GL_FLOAT) {
+        Prepare(typeParam, sizeParam, arrayLen);
+        float *ptr = (float*) data;
+        double *tmpd = new double[arrayLen];
+        if (js_ArrayToJSDoubleBuffer(ctx, arrayObj, 0, arrayLen, tmpd)) {
+            for (PRUint32 i = 0; i < arrayLen; i++)
+                ptr[i] = (float) tmpd[i];
+        } else {
+            for (PRUint32 i = 0; i < arrayLen; i++) {
+                jsval jv;
+                jsdouble dv;
+                ::JS_GetElement(ctx, arrayObj, i, &jv);
+                ::JS_ValueToNumber(ctx, jv, &dv);
+                *ptr++ = (float) dv;
+            }
+        }
+        delete [] tmpd;
+    } else if (typeParam == LOCAL_GL_UNSIGNED_BYTE) {
+        Prepare(typeParam, sizeParam, arrayLen);
+        unsigned char *ptr = (unsigned char*) data;
+        if (!js_ArrayToJSUint8Buffer(ctx, arrayObj, 0, arrayLen, ptr)) {
+            for (PRUint32 i = 0; i < arrayLen; i++) {
+                jsval jv;
+                uint32 iv;
+                ::JS_GetElement(ctx, arrayObj, i, &jv);
+                ::JS_ValueToECMAUint32(ctx, jv, &iv);
+                *ptr++ = (unsigned char) iv;
+            }
+        }
+    } else if (typeParam == LOCAL_GL_UNSIGNED_SHORT) {
+        Prepare(typeParam, sizeParam, arrayLen);
+        PRUint16 *ptr = (PRUint16*) data;
+        if (!js_ArrayToJSUint16Buffer(ctx, arrayObj, 0, arrayLen, ptr)) {
+            for (PRUint32 i = 0; i < arrayLen; i++) {
+                jsval jv;
+                uint32 iv;
+                ::JS_GetElement(ctx, arrayObj, i, &jv);
+                ::JS_ValueToECMAUint32(ctx, jv, &iv);
+                *ptr++ = (unsigned short) iv;
+            }
+        }
+    } else if (typeParam == LOCAL_GL_UNSIGNED_INT) {
+        Prepare(typeParam, sizeParam, arrayLen);
+        PRUint32 *ptr = (PRUint32*) data;
+        if (!js_ArrayToJSUint32Buffer(ctx, arrayObj, 0, arrayLen, ptr)) {
+            for (PRUint32 i = 0; i < arrayLen; i++) {
+                jsval jv;
+                uint32 iv;
+                ::JS_GetElement(ctx, arrayObj, i, &jv);
+                ::JS_ValueToECMAUint32(ctx, jv, &iv);
+                *ptr++ = iv;
+            }
+        }
+    } else if (typeParam == LOCAL_GL_INT) {
+        Prepare(typeParam, sizeParam, arrayLen);
+        PRInt32 *ptr = (PRInt32*) data;
+        if (!js_ArrayToJSInt32Buffer(ctx, arrayObj, 0, arrayLen, ptr)) {
+            for (PRUint32 i = 0; i < arrayLen; i++) {
+                jsval jv;
+                int32 iv;
+                ::JS_GetElement(ctx, arrayObj, i, &jv);
+                ::JS_ValueToECMAInt32(ctx, jv, &iv);
+                *ptr++ = iv;
+            }
+        }
+    } else {
+        return PR_FALSE;
+    }
+
+    return PR_TRUE;
+}
+
new file mode 100644
--- /dev/null
+++ b/content/canvas/src/SimpleBuffer.h
@@ -0,0 +1,146 @@
+/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is mozilla.org code.
+ *
+ * The Initial Developer of the Original Code is
+ *   Mozilla Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 2007
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   Vladimir Vukicevic <vladimir@pobox.com> (original author)
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#ifndef SIMPLEBUFFER_H_
+#define SIMPLEBUFFER_H_
+
+#include "nsICanvasRenderingContextWebGL.h"
+#include "localgl.h"
+
+#include "jsapi.h"
+
+namespace mozilla {
+
+class SimpleBuffer {
+public:
+    SimpleBuffer()
+      : type(LOCAL_GL_FLOAT), data(nsnull), length(0), capacity(0), sizePerVertex(0)
+    { }
+
+    SimpleBuffer(PRUint32 typeParam,
+                 PRUint32 sizeParam,
+                 JSContext *ctx,
+                 JSObject *arrayObj,
+                 jsuint arrayLen)
+      : type(LOCAL_GL_FLOAT), data(nsnull), length(0), capacity(0), sizePerVertex(0)
+    {
+        InitFromJSArray(typeParam, sizeParam, ctx, arrayObj, arrayLen);
+    }
+
+    PRBool InitFromJSArray(PRUint32 typeParam,
+                           PRUint32 sizeParam,
+                           JSContext *ctx,
+                           JSObject *arrayObj,
+                           jsuint arrayLen);
+
+    ~SimpleBuffer() {
+        Release();
+    }
+
+    inline PRBool Valid() {
+        return data != nsnull;
+    }
+
+    inline PRUint32 ElementSize() {
+        if (type == LOCAL_GL_FLOAT) return sizeof(float);
+        if (type == LOCAL_GL_SHORT) return sizeof(short);
+        if (type == LOCAL_GL_UNSIGNED_SHORT) return sizeof(unsigned short);
+        if (type == LOCAL_GL_BYTE) return 1;
+        if (type == LOCAL_GL_UNSIGNED_BYTE) return 1;
+        if (type == LOCAL_GL_INT) return sizeof(int);
+        if (type == LOCAL_GL_UNSIGNED_INT) return sizeof(unsigned int);
+        if (type == LOCAL_GL_DOUBLE) return sizeof(double);
+        return 1;
+    }
+
+    void Clear() {
+        Release();
+    }
+
+    void Set(PRUint32 t, PRUint32 spv, PRUint32 count, void* vals) {
+        Prepare(t, spv, count);
+
+        if (count)
+            memcpy(data, vals, count*ElementSize());
+    }
+
+    void Prepare(PRUint32 t, PRUint32 spv, PRUint32 count) {
+        if (count == 0) {
+            Release();
+        } else {
+            type = t;
+            EnsureCapacity(PR_FALSE, count*ElementSize());
+            length = count;
+            sizePerVertex = spv;
+        }
+    }
+
+    void Release() {
+        if (data)
+            free(data);
+        length = 0;
+        capacity = 0;
+        data = nsnull;
+    }
+
+    void Zero() {
+        memset(data, 0, capacity);
+    }
+
+    void EnsureCapacity(PRBool preserve, PRUint32 cap) {
+        if (capacity >= cap)
+            return;
+
+        void* newdata = malloc(cap);
+        if (preserve && length)
+            memcpy(newdata, data, length*ElementSize());
+        free(data);
+        data = newdata;
+        capacity = cap;
+    }
+
+    PRUint32 type;
+    void* data;
+    PRUint32 length;        // # of elements
+    PRUint32 capacity;      // bytes!
+    PRUint32 sizePerVertex; // OpenGL "size" param; num coordinates per vertex
+};
+
+}
+
+#endif
new file mode 100644
--- /dev/null
+++ b/content/canvas/src/WebGLArrays.cpp
@@ -0,0 +1,2421 @@
+/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is mozilla.org code.
+ *
+ * The Initial Developer of the Original Code is
+ *   Mozilla Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 2009
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   Mark Steele <mwsteele@gmail.com>
+ *   Vladimir Vukicevic <vladimir@pobox.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include "WebGLArrays.h"
+
+#include "NativeJSContext.h"
+
+// TODO:
+// XXX: fix overflow in integer mult in ::Set!
+// XXX: get rid of code duplication, use inline helpers, templates, or macros
+// XXX: Prepare/Zero in initializers is inefficient, we should really
+//      just be doing calloc
+// XXX: array Set() shouldn't call into the inner Set(), because that
+//      repeats the length check and is probably not getting inlined
+// write benchmarks
+
+using namespace mozilla;
+
+nsresult
+NS_NewWebGLArrayBuffer(nsISupports **aResult)
+{
+    nsIWebGLArrayBuffer *wgab = new WebGLArrayBuffer();
+    if (!wgab)
+        return NS_ERROR_OUT_OF_MEMORY;
+
+    NS_ADDREF(*aResult = wgab);
+    return NS_OK;
+}
+
+WebGLArrayBuffer::WebGLArrayBuffer(PRUint32 length)
+{
+    EnsureCapacity(PR_FALSE, length);
+}
+
+NS_IMETHODIMP
+WebGLArrayBuffer::Initialize(nsISupports *owner,
+                             JSContext *cx,
+                             JSObject *obj,
+                             PRUint32 argc,
+                             jsval *argv)
+{
+    /* Constructor: WebGLArrayBuffer(n) */
+    if (JSVAL_IS_NUMBER(argv[0])) {
+        uint32 length;
+        ::JS_ValueToECMAUint32(cx, argv[0], &length);
+        if (length == 0)
+            return NS_ERROR_FAILURE;
+
+        EnsureCapacity(PR_FALSE, length);
+
+        return NS_OK;
+    }
+
+    return NS_ERROR_DOM_SYNTAX_ERR;
+}
+
+/* readonly attribute unsigned long byteLength; */
+NS_IMETHODIMP WebGLArrayBuffer::GetByteLength(PRUint32 *aByteLength)
+{
+    *aByteLength = capacity;
+    return NS_OK;
+}
+
+/* [noscript, notxpcom] voidPtr GetNativeArrayBuffer (); */
+NS_IMETHODIMP_(WebGLArrayBuffer *) WebGLArrayBuffer::GetNativeArrayBuffer()
+{
+    return this;
+}
+
+/* [noscript, notxpcom] voidPtr nativePointer (); */
+NS_IMETHODIMP_(void *) WebGLArrayBuffer::NativePointer()
+{
+    return data;
+}
+
+/* [noscript, notxpcom] unsigned long nativeSize (); */
+NS_IMETHODIMP_(PRUint32) WebGLArrayBuffer::NativeSize()
+{
+    return capacity;
+}
+
+/*
+ * WebGLFloatArray
+ */
+
+nsresult
+NS_NewWebGLFloatArray(nsISupports **aResult)
+{
+    nsIWebGLFloatArray *wgfa = new WebGLFloatArray();
+    if (!wgfa)
+        return NS_ERROR_OUT_OF_MEMORY;
+
+    NS_ADDREF(*aResult = wgfa);
+    return NS_OK;
+}
+
+WebGLFloatArray::WebGLFloatArray(PRUint32 length)
+    : mOffset(0), mLength(length)
+{
+    mBuffer = new WebGLArrayBuffer(length * sizeof(float));
+}
+
+WebGLFloatArray::WebGLFloatArray(WebGLArrayBuffer *buffer, PRUint32 offset, PRUint32 length)
+    : mBuffer(buffer), mOffset(offset), mLength(length)
+{
+}
+
+WebGLFloatArray::WebGLFloatArray(JSContext *cx, JSObject *arrayObj, jsuint arrayLen)
+    : mOffset(0), mLength(arrayLen)
+{
+    mBuffer = new WebGLArrayBuffer();
+    mBuffer->InitFromJSArray(LOCAL_GL_FLOAT, 1, cx, arrayObj, arrayLen);
+}
+
+NS_IMETHODIMP
+WebGLFloatArray::Initialize(nsISupports *owner,
+                            JSContext *cx,
+                            JSObject *obj,
+                            PRUint32 argc,
+                            jsval *argv)
+{
+    if (JSVAL_IS_NUMBER(argv[0])) {
+        uint32 length;
+        ::JS_ValueToECMAUint32(cx, argv[0], &length);
+        mBuffer = new WebGLArrayBuffer();
+        mBuffer->Prepare(LOCAL_GL_FLOAT, 1, length);
+        mBuffer->Zero();
+        mLength = length;
+    } else {
+        JSObject *arrayObj;
+        jsuint arrayLen;
+        jsuint byteOffset = 0;
+        jsuint length = 0;
+
+        if (!::JS_ConvertArguments(cx, argc, argv, "o/uu", &arrayObj, &byteOffset, &length) ||
+            arrayObj == NULL)
+        {
+            return NS_ERROR_DOM_SYNTAX_ERR;
+        }
+
+        if (::JS_IsArrayObject(cx, arrayObj) &&
+            ::JS_GetArrayLength(cx, arrayObj, &arrayLen))
+        {
+            mBuffer = new WebGLArrayBuffer();
+            mBuffer->InitFromJSArray(LOCAL_GL_FLOAT, 1, cx, arrayObj, arrayLen);
+            mLength = arrayLen;
+        } else {
+            nsCOMPtr<nsIWebGLArrayBuffer> canvasObj;
+            nsresult rv;
+            rv = nsContentUtils::XPConnect()->WrapJS(cx, arrayObj, NS_GET_IID(nsIWebGLArrayBuffer), getter_AddRefs(canvasObj));
+            if (NS_FAILED(rv) || !canvasObj) {
+                return NS_ERROR_DOM_SYNTAX_ERR;
+            }
+
+            mBuffer = canvasObj->GetNativeArrayBuffer();
+
+            if (byteOffset % sizeof(float))
+                return NS_ERROR_FAILURE;
+
+            if ((byteOffset + (length * sizeof(float))) > mBuffer->capacity)
+                return NS_ERROR_FAILURE;
+
+            if (length > 0) {
+                mLength = length;
+            } else {
+                if ((mBuffer->capacity - byteOffset) % sizeof(float))
+                    return NS_ERROR_FAILURE;
+
+                mLength = (mBuffer->capacity - byteOffset) / sizeof(float);
+            }
+        }
+    }
+
+    return NS_OK;
+}
+
+/* readonly attribute nsIWebGLArrayBuffer buffer; */
+NS_IMETHODIMP WebGLFloatArray::GetBuffer(nsIWebGLArrayBuffer **aBuffer)
+{
+    NS_ADDREF(*aBuffer = mBuffer);
+    return NS_OK;
+}
+
+/* readonly attribute unsigned long byteOffset; */
+NS_IMETHODIMP WebGLFloatArray::GetByteOffset(PRUint32 *aByteOffset)
+{
+    *aByteOffset = mOffset;
+    return NS_OK;
+}
+
+/* readonly attribute unsigned long byteLength; */
+NS_IMETHODIMP WebGLFloatArray::GetByteLength(PRUint32 *aByteLength)
+{
+    *aByteLength = mLength * sizeof(float);
+    return NS_OK;
+}
+
+/* attribute unsigned long length; */
+NS_IMETHODIMP WebGLFloatArray::GetLength(PRUint32 *aLength)
+{
+    *aLength = mLength;
+    return NS_OK;
+}
+
+/* unsigned long alignedSizeInBytes (); */
+NS_IMETHODIMP WebGLFloatArray::AlignedSizeInBytes(PRUint32 *retval)
+{
+    *retval = mBuffer->capacity;
+    return NS_OK;
+}
+
+/* nsIWebGLArray slice (in unsigned long offset, in unsigned long length); */
+NS_IMETHODIMP WebGLFloatArray::Slice(PRUint32 offset, PRUint32 length, nsIWebGLArray **retval)
+{
+    if (length == 0) 
+        return NS_ERROR_FAILURE;
+
+    if (offset + length > mBuffer->capacity)
+        return NS_ERROR_FAILURE;
+
+    nsIWebGLArray *wga = new WebGLFloatArray(mBuffer, offset, length);
+    NS_ADDREF(*retval = wga);
+    return NS_OK;
+}
+
+/* [IndexGetter] float get (in unsigned long index); */
+NS_IMETHODIMP WebGLFloatArray::Get(PRUint32 index, float *retval)
+{
+    if (index >= mLength)
+        return NS_ERROR_FAILURE;
+
+    float *values = static_cast<float*>(mBuffer->data);
+    *retval = values[index];
+
+    return NS_OK;
+}
+
+void
+WebGLFloatArray::Set(PRUint32 index, float value)
+{
+    if (index >= mLength)
+        return;
+
+    float *values = static_cast<float*>(mBuffer->data);
+    values[index] = value;
+}
+
+/* void set (); */
+NS_IMETHODIMP WebGLFloatArray::Set()
+{
+    NativeJSContext js;
+    if (NS_FAILED(js.error))
+        return js.error;
+
+    if (js.argc < 1 || js.argc > 2)
+        return NS_ERROR_DOM_SYNTAX_ERR;
+
+    if (JSVAL_IS_NUMBER(js.argv[0])) {
+        if (js.argc != 2)
+            return NS_ERROR_DOM_SYNTAX_ERR;
+
+        uint32 index;
+        ::JS_ValueToECMAUint32(js.ctx, js.argv[0], &index);
+
+        jsdouble value;
+        ::JS_ValueToNumber(js.ctx, js.argv[1], &value);
+
+        if (index >= mLength)
+            return NS_ERROR_FAILURE;
+
+        Set(index, (float) value);
+    } else {
+        return NS_ERROR_NOT_IMPLEMENTED;
+    }
+
+    return NS_OK;
+}
+
+NS_IMETHODIMP_(PRUint32) WebGLFloatArray::NativeType()
+{
+    return mBuffer->type;
+}
+
+/* [noscript, notxpcom] voidPtr nativePointer (); */
+NS_IMETHODIMP_(void *) WebGLFloatArray::NativePointer()
+{
+    return mBuffer->data;
+}
+
+/* [noscript, notxpcom] unsigned long nativeSize (); */
+NS_IMETHODIMP_(PRUint32) WebGLFloatArray::NativeSize()
+{
+    return mBuffer->capacity;
+}
+
+/* [noscript, notxpcom] unsigned long nativeElementSize (); */
+NS_IMETHODIMP_(PRUint32) WebGLFloatArray::NativeElementSize()
+{
+    return mBuffer->ElementSize();
+}
+
+/* [noscript, notxpcom] unsigned long nativeCount (); */
+NS_IMETHODIMP_(PRUint32) WebGLFloatArray::NativeCount()
+{
+    return mBuffer->length;
+}
+
+// nsIXPCScriptable
+#define XPC_MAP_CLASSNAME WebGLFloatArray
+#define XPC_MAP_QUOTED_CLASSNAME "WebGLFloatArray"
+#define XPC_MAP_WANT_SETPROPERTY
+#define XPC_MAP_WANT_GETPROPERTY
+#define XPC_MAP_WANT_NEWRESOLVE
+#define XPC_MAP_FLAGS nsIXPCScriptable::USE_JSSTUB_FOR_ADDPROPERTY
+#include "xpc_map_end.h"
+
+PRBool WebGLFloatArray::JSValToIndex(JSContext *cx, jsval id, uint32 *retval) {
+    PRBool ok = PR_FALSE;
+    uint32 index;
+
+    if (JSVAL_IS_INT(id)) {
+        index = JSVAL_TO_INT(id);
+        ok = PR_TRUE;
+    } else {
+        ok = JS_ValueToECMAUint32(cx, id, &index);
+    }
+
+    if (!ok || index >= mLength)
+        return PR_FALSE;
+
+    *retval = index;
+    return PR_TRUE;
+}
+
+NS_IMETHODIMP WebGLFloatArray::GetProperty(nsIXPConnectWrappedNative *wrapper, JSContext * cx,
+                                           JSObject * obj, jsval id, jsval * vp, PRBool *_retval)
+{
+    uint32 index;
+    
+    if (!JSValToIndex(cx, id, &index)) {
+        *_retval = PR_FALSE;
+        return NS_ERROR_INVALID_ARG;
+    }
+
+    float val;
+    Get(index, &val);
+    *_retval = JS_NewNumberValue(cx, val, vp);
+
+    return NS_OK;
+}
+
+NS_IMETHODIMP WebGLFloatArray::SetProperty(nsIXPConnectWrappedNative *wrapper, JSContext * cx,
+                       JSObject * obj, jsval id, jsval * vp, PRBool *_retval)
+{
+    uint32 index;
+    float val;
+
+    if (!JSValToIndex(cx, id, &index)) {
+        *_retval = PR_FALSE;
+        return NS_ERROR_INVALID_ARG;
+    }
+
+    PRBool ok = PR_FALSE;
+
+    if (JSVAL_IS_INT(*vp)) {
+        val = (float) JSVAL_TO_INT(*vp);
+        ok = PR_TRUE;
+    } else {
+        jsdouble dval;
+        ok = JS_ValueToNumber(cx, *vp, &dval);
+        val = (float) dval;
+    }
+
+    if (!ok) {
+        *_retval = PR_FALSE;
+        return NS_ERROR_INVALID_ARG;
+    }
+
+    Set(index, val);
+    return NS_OK;
+}
+
+NS_IMETHODIMP WebGLFloatArray::NewResolve(nsIXPConnectWrappedNative *wrapper, JSContext * cx,
+                      JSObject * obj, jsval id, PRUint32 flags, JSObject * *objp,
+                      PRBool *_retval)
+{
+    uint32 index;
+    PRBool ok = JSValToIndex(cx, id, &index);
+
+    if (ok) {
+        *_retval = PR_TRUE;
+        *objp = obj;
+    } else {
+        *_retval = PR_FALSE;
+        return NS_ERROR_FAILURE;
+    }
+
+    return NS_OK;
+}
+
+/*
+ * WebGLByteArray
+ */
+
+nsresult
+NS_NewWebGLByteArray(nsISupports **aResult)
+{
+    nsIWebGLByteArray *wgba = new WebGLByteArray();
+    if (!wgba)
+        return NS_ERROR_OUT_OF_MEMORY;
+
+    NS_ADDREF(*aResult = wgba);
+    return NS_OK;
+}
+
+WebGLByteArray::WebGLByteArray(PRUint32 length)
+    : mOffset(0), mLength(length)
+{
+    mBuffer = new WebGLArrayBuffer(length);
+}
+
+WebGLByteArray::WebGLByteArray(WebGLArrayBuffer *buffer, PRUint32 offset, PRUint32 length)
+    : mBuffer(buffer), mOffset(offset), mLength(length)
+{
+}
+
+WebGLByteArray::WebGLByteArray(JSContext *cx, JSObject *arrayObj, jsuint arrayLen)
+    : mOffset(0), mLength(arrayLen)
+{
+    mBuffer = new WebGLArrayBuffer();
+    mBuffer->InitFromJSArray(LOCAL_GL_UNSIGNED_BYTE, 1, cx, arrayObj, arrayLen);
+}
+
+NS_IMETHODIMP
+WebGLByteArray::Initialize(nsISupports *owner,
+                           JSContext *cx,
+                           JSObject *obj,
+                           PRUint32 argc,
+                           jsval *argv)
+{
+    if (JSVAL_IS_NUMBER(argv[0])) {
+        uint32 length;
+        ::JS_ValueToECMAUint32(cx, argv[0], &length);
+        mBuffer = new WebGLArrayBuffer();
+        mBuffer->Prepare(LOCAL_GL_BYTE, 1, length);
+        mBuffer->Zero();
+        mLength = length;
+    } else {
+        JSObject *arrayObj;
+        jsuint arrayLen;
+        jsuint byteOffset = 0;
+        jsuint length = 0;
+
+        if (!::JS_ConvertArguments(cx, argc, argv, "o/uu", &arrayObj, &byteOffset, &length) ||
+            arrayObj == NULL)
+        {
+            return NS_ERROR_DOM_SYNTAX_ERR;
+        }
+
+        if (::JS_IsArrayObject(cx, arrayObj) &&
+            ::JS_GetArrayLength(cx, arrayObj, &arrayLen))
+        {
+            mBuffer = new WebGLArrayBuffer();
+            mBuffer->InitFromJSArray(LOCAL_GL_UNSIGNED_BYTE, 1, cx, arrayObj, arrayLen);
+            mLength = arrayLen;
+        } else {
+            nsCOMPtr<nsIWebGLArrayBuffer> canvasObj;
+            nsresult rv;
+            rv = nsContentUtils::XPConnect()->WrapJS(cx, arrayObj, NS_GET_IID(nsIWebGLArrayBuffer), getter_AddRefs(canvasObj));
+            if (NS_FAILED(rv) || !canvasObj) {
+                return NS_ERROR_DOM_SYNTAX_ERR;
+            }
+
+            mBuffer = canvasObj->GetNativeArrayBuffer();
+
+            if ((byteOffset + length) > mBuffer->capacity)
+                return NS_ERROR_FAILURE;
+
+            if (length > 0)
+                mLength = length;
+            else
+                mLength = (mBuffer->capacity - byteOffset);
+        }
+    }
+
+    return NS_OK;
+}
+
+/* readonly attribute nsIWebGLArrayBuffer buffer; */
+NS_IMETHODIMP WebGLByteArray::GetBuffer(nsIWebGLArrayBuffer **aBuffer)
+{
+    NS_ADDREF(*aBuffer = mBuffer);
+    return NS_OK;
+}
+
+/* readonly attribute unsigned long byteOffset; */
+NS_IMETHODIMP WebGLByteArray::GetByteOffset(PRUint32 *aByteOffset)
+{
+    *aByteOffset = mOffset;
+    return NS_OK;
+}
+
+/* readonly attribute unsigned long byteLength; */
+NS_IMETHODIMP WebGLByteArray::GetByteLength(PRUint32 *aByteLength)
+{
+    *aByteLength = mLength;
+    return NS_OK;
+}
+
+/* attribute unsigned long length; */
+NS_IMETHODIMP WebGLByteArray::GetLength(PRUint32 *aLength)
+{
+    *aLength = mLength;
+    return NS_OK;
+}
+
+/* unsigned long alignedSizeInBytes (); */
+NS_IMETHODIMP WebGLByteArray::AlignedSizeInBytes(PRUint32 *retval)
+{
+    *retval = mBuffer->capacity;
+    return NS_OK;
+}
+
+/* nsIWebGLArray slice (in unsigned long offset, in unsigned long length); */
+NS_IMETHODIMP WebGLByteArray::Slice(PRUint32 offset, PRUint32 length, nsIWebGLArray **retval)
+{
+    if (length == 0) 
+        return NS_ERROR_FAILURE;
+
+    if (offset + length > mBuffer->capacity)
+        return NS_ERROR_FAILURE;
+
+    nsIWebGLArray *wga = new WebGLByteArray(mBuffer, offset, length);
+    NS_ADDREF(*retval = wga);
+    return NS_OK;
+}
+
+/* [IndexGetter] long get (in unsigned long index); */
+NS_IMETHODIMP WebGLByteArray::Get(PRUint32 index, PRInt32 *retval)
+{
+    if (index >= mLength)
+        return NS_ERROR_FAILURE;
+
+    char *values = static_cast<char*>(mBuffer->data);
+    *retval = values[index];
+
+    return NS_OK;
+}
+
+void
+WebGLByteArray::Set(PRUint32 index, char value)
+{
+    if (index >= mLength)
+        return;
+
+    char *values = static_cast<char*>(mBuffer->data);
+    values[index] = value;
+}
+
+/* void set (); */
+NS_IMETHODIMP WebGLByteArray::Set()
+{
+    NativeJSContext js;
+    if (NS_FAILED(js.error))
+        return js.error;
+
+    if (js.argc < 1 || js.argc > 2)
+        return NS_ERROR_DOM_SYNTAX_ERR;
+
+    if (JSVAL_IS_NUMBER(js.argv[0])) {
+        if (js.argc != 2)
+            return NS_ERROR_DOM_SYNTAX_ERR;
+
+        uint32 index;
+        ::JS_ValueToECMAUint32(js.ctx, js.argv[0], &index);
+
+        int32 value;
+        ::JS_ValueToECMAInt32(js.ctx, js.argv[1], &value);
+
+        if (index >= mLength)
+            return NS_ERROR_FAILURE;
+
+        Set(index, (char) value);
+    } else {
+        return NS_ERROR_NOT_IMPLEMENTED;
+    }
+
+    return NS_OK;
+}
+
+NS_IMETHODIMP_(PRUint32) WebGLByteArray::NativeType()
+{
+    return mBuffer->type;
+}
+
+/* [noscript, notxpcom] voidPtr nativePointer (); */
+NS_IMETHODIMP_(void *) WebGLByteArray::NativePointer()
+{
+    return mBuffer->data;
+}
+
+/* [noscript, notxpcom] unsigned long nativeSize (); */
+NS_IMETHODIMP_(PRUint32) WebGLByteArray::NativeSize()
+{
+    return mBuffer->capacity;
+}
+
+/* [noscript, notxpcom] unsigned long nativeElementSize (); */
+NS_IMETHODIMP_(PRUint32) WebGLByteArray::NativeElementSize()
+{
+    return mBuffer->ElementSize();
+}
+
+/* [noscript, notxpcom] unsigned long nativeCount (); */
+NS_IMETHODIMP_(PRUint32) WebGLByteArray::NativeCount()
+{
+    return mBuffer->length;
+}
+
+// nsIXPCScriptable
+#define XPC_MAP_CLASSNAME WebGLByteArray
+#define XPC_MAP_QUOTED_CLASSNAME "WebGLByteArray"
+#define XPC_MAP_WANT_SETPROPERTY
+#define XPC_MAP_WANT_GETPROPERTY
+#define XPC_MAP_WANT_NEWRESOLVE
+#define XPC_MAP_FLAGS nsIXPCScriptable::USE_JSSTUB_FOR_ADDPROPERTY
+#include "xpc_map_end.h"
+
+PRBool WebGLByteArray::JSValToIndex(JSContext *cx, jsval id, uint32 *retval) {
+    PRBool ok = PR_FALSE;
+    uint32 index;
+
+    if (JSVAL_IS_INT(id)) {
+        index = JSVAL_TO_INT(id);
+        ok = PR_TRUE;
+    } else {
+        ok = JS_ValueToECMAUint32(cx, id, &index);
+    }
+
+    if (!ok || index >= mLength)
+        return PR_FALSE;
+
+    *retval = index;
+    return PR_TRUE;
+}
+
+NS_IMETHODIMP WebGLByteArray::GetProperty(nsIXPConnectWrappedNative *wrapper, JSContext * cx,
+                                          JSObject * obj, jsval id, jsval * vp, PRBool *_retval)
+{
+    uint32 index;
+    
+    if (!JSValToIndex(cx, id, &index)) {
+        *_retval = PR_FALSE;
+        return NS_ERROR_INVALID_ARG;
+    }
+
+    PRInt32 val;
+    Get(index, &val);
+    *_retval = JS_NewNumberValue(cx, val, vp);
+
+    return NS_SUCCESS_I_DID_SOMETHING;
+}
+
+NS_IMETHODIMP WebGLByteArray::SetProperty(nsIXPConnectWrappedNative *wrapper, JSContext * cx,
+                                          JSObject * obj, jsval id, jsval * vp, PRBool *_retval)
+{
+    uint32 index;
+    int32 val;
+
+    if (!JSValToIndex(cx, id, &index)) {
+        *_retval = PR_FALSE;
+        return NS_ERROR_INVALID_ARG;
+    }
+
+    PRBool ok = PR_FALSE;
+
+    if (JSVAL_IS_INT(*vp)) {
+        val = JSVAL_TO_INT(*vp);
+        ok = PR_TRUE;
+    } else {
+        ok = JS_ValueToECMAInt32(cx, *vp, &val);
+    }
+
+    if (!ok) {
+        *_retval = PR_FALSE;
+        return NS_ERROR_INVALID_ARG;
+    }
+
+    Set(index, (char) val);
+    return NS_SUCCESS_I_DID_SOMETHING;
+}
+
+NS_IMETHODIMP WebGLByteArray::NewResolve(nsIXPConnectWrappedNative *wrapper, JSContext * cx,
+                                         JSObject * obj, jsval id, PRUint32 flags, JSObject * *objp,
+                                         PRBool *_retval)
+{
+    uint32 index;
+    PRBool ok = JSValToIndex(cx, id, &index);
+
+    if (ok) {
+        *_retval = PR_TRUE;
+        *objp = obj;
+    } else {
+        *_retval = PR_FALSE;
+        return NS_ERROR_FAILURE;
+    }
+
+    return NS_OK;
+}
+
+/*
+ * WebGLUnsignedByteArray
+ */
+
+nsresult
+NS_NewWebGLUnsignedByteArray(nsISupports **aResult)
+{
+    nsIWebGLUnsignedByteArray *wguba = new WebGLUnsignedByteArray();
+    if (!wguba)
+        return NS_ERROR_OUT_OF_MEMORY;
+
+    NS_ADDREF(*aResult = wguba);
+    return NS_OK;
+}
+
+WebGLUnsignedByteArray::WebGLUnsignedByteArray(PRUint32 length)
+    : mOffset(0), mLength(length)
+{
+    mBuffer = new WebGLArrayBuffer(length);
+}
+
+WebGLUnsignedByteArray::WebGLUnsignedByteArray(WebGLArrayBuffer *buffer, PRUint32 offset, PRUint32 length)
+    : mBuffer(buffer), mOffset(offset), mLength(length)
+{
+}
+
+WebGLUnsignedByteArray::WebGLUnsignedByteArray(JSContext *cx, JSObject *arrayObj, jsuint arrayLen)
+    : mOffset(0), mLength(arrayLen)
+{
+    mBuffer = new WebGLArrayBuffer();
+    mBuffer->InitFromJSArray(LOCAL_GL_UNSIGNED_BYTE, 1, cx, arrayObj, arrayLen);
+}
+
+NS_IMETHODIMP
+WebGLUnsignedByteArray::Initialize(nsISupports *owner,
+                                   JSContext *cx,
+                                   JSObject *obj,
+                                   PRUint32 argc,
+                                   jsval *argv)
+{
+    if (JSVAL_IS_NUMBER(argv[0])) {
+        uint32 length;
+        ::JS_ValueToECMAUint32(cx, argv[0], &length);
+        mBuffer = new WebGLArrayBuffer();
+        mBuffer->Prepare(LOCAL_GL_UNSIGNED_BYTE, 1, length);
+        mBuffer->Zero();
+        mLength = length;
+    } else {
+        JSObject *arrayObj;
+        jsuint arrayLen;
+        jsuint byteOffset = 0;
+        jsuint length = 0;
+
+        if (!::JS_ConvertArguments(cx, argc, argv, "o/uu", &arrayObj, &byteOffset, &length) ||
+            arrayObj == NULL)
+        {
+            return NS_ERROR_DOM_SYNTAX_ERR;
+        }
+
+        if (::JS_IsArrayObject(cx, arrayObj) &&
+            ::JS_GetArrayLength(cx, arrayObj, &arrayLen))
+        {
+            mBuffer = new WebGLArrayBuffer();
+            mBuffer->InitFromJSArray(LOCAL_GL_UNSIGNED_BYTE, 1, cx, arrayObj, arrayLen);
+            mLength = arrayLen;
+        } else {
+            nsCOMPtr<nsIWebGLArrayBuffer> canvasObj;
+            nsresult rv;
+            rv = nsContentUtils::XPConnect()->WrapJS(cx, arrayObj, NS_GET_IID(nsIWebGLArrayBuffer), getter_AddRefs(canvasObj));
+            if (NS_FAILED(rv) || !canvasObj) {
+                return NS_ERROR_DOM_SYNTAX_ERR;
+            }
+
+            mBuffer = canvasObj->GetNativeArrayBuffer();
+
+            if ((byteOffset + length) > mBuffer->capacity)
+                return NS_ERROR_FAILURE;
+
+            if (length > 0)
+                mLength = length;
+            else
+                mLength = (mBuffer->capacity - byteOffset);
+        }
+    }
+
+    return NS_OK;
+}
+
+/* readonly attribute nsIWebGLArrayBuffer buffer; */
+NS_IMETHODIMP WebGLUnsignedByteArray::GetBuffer(nsIWebGLArrayBuffer **aBuffer)
+{
+    NS_ADDREF(*aBuffer = mBuffer);
+    return NS_OK;
+}
+
+/* readonly attribute unsigned long byteOffset; */
+NS_IMETHODIMP WebGLUnsignedByteArray::GetByteOffset(PRUint32 *aByteOffset)
+{
+    *aByteOffset = mOffset;
+    return NS_OK;
+}
+
+/* readonly attribute unsigned long byteLength; */
+NS_IMETHODIMP WebGLUnsignedByteArray::GetByteLength(PRUint32 *aByteLength)
+{
+    *aByteLength = mLength;
+    return NS_OK;
+}
+
+/* attribute unsigned long length; */
+NS_IMETHODIMP WebGLUnsignedByteArray::GetLength(PRUint32 *aLength)
+{
+    *aLength = mLength;
+    return NS_OK;
+}
+
+/* unsigned long alignedSizeInBytes (); */
+NS_IMETHODIMP WebGLUnsignedByteArray::AlignedSizeInBytes(PRUint32 *retval)
+{
+    *retval = mBuffer->capacity;
+    return NS_OK;
+}
+
+/* nsIWebGLArray slice (in unsigned long offset, in unsigned long length); */
+NS_IMETHODIMP WebGLUnsignedByteArray::Slice(PRUint32 offset, PRUint32 length, nsIWebGLArray **retval)
+{
+    if (length == 0) 
+        return NS_ERROR_FAILURE;
+
+    if (offset + length > mBuffer->capacity)
+        return NS_ERROR_FAILURE;
+
+    nsIWebGLArray *wga = new WebGLUnsignedByteArray(mBuffer, offset, length);
+    NS_ADDREF(*retval = wga);
+    return NS_OK;
+}
+
+/* [IndexGetter] unsigned long get (in unsigned long index); */
+NS_IMETHODIMP WebGLUnsignedByteArray::Get(PRUint32 index, PRUint32 *retval)
+{
+    if (index >= mLength)
+        return NS_ERROR_FAILURE;
+
+    unsigned char *values = static_cast<unsigned char*>(mBuffer->data);
+    *retval = values[index];
+
+    return NS_OK;
+}
+
+void
+WebGLUnsignedByteArray::Set(PRUint32 index, unsigned char value)
+{
+    if (index >= mLength)
+        return;
+
+    unsigned char *values = static_cast<unsigned char*>(mBuffer->data);
+    values[index] = value;
+}
+
+/* void set (); */
+NS_IMETHODIMP WebGLUnsignedByteArray::Set()
+{
+    NativeJSContext js;
+    if (NS_FAILED(js.error))
+        return js.error;
+
+    if (js.argc < 1 || js.argc > 2)
+        return NS_ERROR_DOM_SYNTAX_ERR;
+
+    if (JSVAL_IS_NUMBER(js.argv[0])) {
+        if (js.argc != 2)
+            return NS_ERROR_DOM_SYNTAX_ERR;
+
+        uint32 index;
+        ::JS_ValueToECMAUint32(js.ctx, js.argv[0], &index);
+
+        uint32 value;
+        ::JS_ValueToECMAUint32(js.ctx, js.argv[1], &value);
+
+        if (index >= mLength)
+            return NS_ERROR_FAILURE;
+
+        Set(index, (unsigned char) value);
+    } else {
+        return NS_ERROR_NOT_IMPLEMENTED;
+    }
+
+    return NS_OK;
+}
+
+NS_IMETHODIMP_(PRUint32) WebGLUnsignedByteArray::NativeType()
+{
+    return mBuffer->type;
+}
+
+/* [noscript, notxpcom] voidPtr nativePointer (); */
+NS_IMETHODIMP_(void *) WebGLUnsignedByteArray::NativePointer()
+{
+    return mBuffer->data;
+}
+
+/* [noscript, notxpcom] unsigned long nativeSize (); */
+NS_IMETHODIMP_(PRUint32) WebGLUnsignedByteArray::NativeSize()
+{
+    return mBuffer->capacity;
+}
+
+/* [noscript, notxpcom] unsigned long nativeElementSize (); */
+NS_IMETHODIMP_(PRUint32) WebGLUnsignedByteArray::NativeElementSize()
+{
+    return mBuffer->ElementSize();
+}
+
+/* [noscript, notxpcom] unsigned long nativeCount (); */
+NS_IMETHODIMP_(PRUint32) WebGLUnsignedByteArray::NativeCount()
+{
+    return mBuffer->length;
+}
+
+// nsIXPCScriptable
+#define XPC_MAP_CLASSNAME WebGLUnsignedByteArray
+#define XPC_MAP_QUOTED_CLASSNAME "WebGLUnsignedByteArray"
+#define XPC_MAP_WANT_SETPROPERTY
+#define XPC_MAP_WANT_GETPROPERTY
+#define XPC_MAP_WANT_NEWRESOLVE
+#define XPC_MAP_FLAGS nsIXPCScriptable::USE_JSSTUB_FOR_ADDPROPERTY
+#include "xpc_map_end.h"
+
+PRBool WebGLUnsignedByteArray::JSValToIndex(JSContext *cx, jsval id, uint32 *retval) {
+    PRBool ok = PR_FALSE;
+    uint32 index;
+
+    if (JSVAL_IS_INT(id)) {
+        index = JSVAL_TO_INT(id);
+        ok = PR_TRUE;
+    } else {
+        ok = JS_ValueToECMAUint32(cx, id, &index);
+    }
+
+    if (!ok || index >= mLength)
+        return PR_FALSE;
+
+    *retval = index;
+    return PR_TRUE;
+}
+
+NS_IMETHODIMP WebGLUnsignedByteArray::GetProperty(nsIXPConnectWrappedNative *wrapper, JSContext * cx,
+                                                  JSObject * obj, jsval id, jsval * vp, PRBool *_retval)
+{
+    uint32 index;
+    
+    if (!JSValToIndex(cx, id, &index)) {
+        *_retval = PR_FALSE;
+        return NS_ERROR_INVALID_ARG;
+    }
+
+    PRUint32 val;
+    Get(index, &val);
+    *_retval = JS_NewNumberValue(cx, val, vp);
+
+    return NS_OK;
+}
+
+NS_IMETHODIMP WebGLUnsignedByteArray::SetProperty(nsIXPConnectWrappedNative *wrapper, JSContext * cx,
+                                                  JSObject * obj, jsval id, jsval * vp, PRBool *_retval)
+{
+    uint32 index;
+    uint32 val;
+
+    if (!JSValToIndex(cx, id, &index)) {
+        *_retval = PR_FALSE;
+        return NS_ERROR_INVALID_ARG;
+    }
+
+    PRBool ok = PR_FALSE;
+
+    if (JSVAL_IS_INT(*vp)) {
+        val = JSVAL_TO_INT(*vp);
+        ok = PR_TRUE;
+    } else {
+        ok = JS_ValueToECMAUint32(cx, *vp, &val);
+    }
+
+    if (!ok) {
+        *_retval = PR_FALSE;
+        return NS_ERROR_INVALID_ARG;
+    }
+
+    Set(index, (unsigned char) val);
+    return NS_OK;
+}
+
+NS_IMETHODIMP WebGLUnsignedByteArray::NewResolve(nsIXPConnectWrappedNative *wrapper, JSContext * cx,
+                                                 JSObject * obj, jsval id, PRUint32 flags, JSObject * *objp,
+                                                 PRBool *_retval)
+{
+    uint32 index;
+    PRBool ok = JSValToIndex(cx, id, &index);
+
+    if (ok) {
+        *_retval = PR_TRUE;
+        *objp = obj;
+    } else {
+        *_retval = PR_FALSE;
+        return NS_ERROR_FAILURE;
+    }
+
+    return NS_OK;
+}
+
+/*
+ * WebGLShortArray
+ */
+
+nsresult
+NS_NewWebGLShortArray(nsISupports **aResult)
+{
+    nsIWebGLShortArray *wgsa = new WebGLShortArray();
+    if (!wgsa)
+        return NS_ERROR_OUT_OF_MEMORY;
+
+    NS_ADDREF(*aResult = wgsa);
+    return NS_OK;
+}
+
+WebGLShortArray::WebGLShortArray(PRUint32 length)
+    : mOffset(0), mLength(length)
+{
+    mBuffer = new WebGLArrayBuffer(length * sizeof(short));
+}
+
+WebGLShortArray::WebGLShortArray(WebGLArrayBuffer *buffer, PRUint32 offset, PRUint32 length)
+    : mBuffer(buffer), mOffset(offset), mLength(length)
+{
+}
+
+WebGLShortArray::WebGLShortArray(JSContext *cx, JSObject *arrayObj, jsuint arrayLen)
+    : mOffset(0), mLength(arrayLen)
+{
+    mBuffer = new WebGLArrayBuffer();
+    mBuffer->InitFromJSArray(LOCAL_GL_SHORT, 1, cx, arrayObj, arrayLen);
+}
+
+NS_IMETHODIMP
+WebGLShortArray::Initialize(nsISupports *owner,
+                            JSContext *cx,
+                            JSObject *obj,
+                            PRUint32 argc,
+                            jsval *argv)
+{
+    if (JSVAL_IS_NUMBER(argv[0])) {
+        uint32 length;
+        ::JS_ValueToECMAUint32(cx, argv[0], &length);
+        mBuffer = new WebGLArrayBuffer();
+        mBuffer->Prepare(LOCAL_GL_SHORT, 1, length);
+        mBuffer->Zero();
+        mLength = length;
+    } else {
+        JSObject *arrayObj;
+        jsuint arrayLen;
+        jsuint byteOffset = 0;
+        jsuint length = 0;
+
+        if (!::JS_ConvertArguments(cx, argc, argv, "o/uu", &arrayObj, &byteOffset, &length) ||
+            arrayObj == NULL)
+        {
+            return NS_ERROR_DOM_SYNTAX_ERR;
+        }
+
+        if (::JS_IsArrayObject(cx, arrayObj) &&
+            ::JS_GetArrayLength(cx, arrayObj, &arrayLen))
+        {
+            mBuffer = new WebGLArrayBuffer();
+            mBuffer->InitFromJSArray(LOCAL_GL_SHORT, 1, cx, arrayObj, arrayLen);
+            mLength = arrayLen;
+        } else {
+            nsCOMPtr<nsIWebGLArrayBuffer> canvasObj;
+            nsresult rv;
+            rv = nsContentUtils::XPConnect()->WrapJS(cx, arrayObj, NS_GET_IID(nsIWebGLArrayBuffer), getter_AddRefs(canvasObj));
+            if (NS_FAILED(rv) || !canvasObj) {
+                return NS_ERROR_DOM_SYNTAX_ERR;
+            }
+
+            mBuffer = canvasObj->GetNativeArrayBuffer();
+
+            if (byteOffset % sizeof(short))
+                return NS_ERROR_FAILURE;
+
+            if ((byteOffset + (length * sizeof(short))) > mBuffer->capacity)
+                return NS_ERROR_FAILURE;
+
+            if (length > 0) {
+                mLength = length;
+            } else {
+                if ((mBuffer->capacity - byteOffset) % sizeof(short))
+                    return NS_ERROR_FAILURE;
+
+                mLength = (mBuffer->capacity - byteOffset) / sizeof(short);
+            }
+        }
+    }
+
+    return NS_OK;
+}
+
+/* readonly attribute nsIWebGLArrayBuffer buffer; */
+NS_IMETHODIMP WebGLShortArray::GetBuffer(nsIWebGLArrayBuffer * *aBuffer)
+{
+    NS_ADDREF(*aBuffer = mBuffer);
+    return NS_OK;
+}
+
+/* readonly attribute unsigned long byteOffset; */
+NS_IMETHODIMP WebGLShortArray::GetByteOffset(PRUint32 *aByteOffset)
+{
+    *aByteOffset = mOffset;
+    return NS_OK;
+}
+
+/* readonly attribute unsigned long byteLength; */
+NS_IMETHODIMP WebGLShortArray::GetByteLength(PRUint32 *aByteLength)
+{
+    *aByteLength = mLength * sizeof(short);
+    return NS_OK;
+}
+
+/* attribute unsigned long length; */
+NS_IMETHODIMP WebGLShortArray::GetLength(PRUint32 *aLength)
+{
+    *aLength = mLength;
+    return NS_OK;
+}
+
+/* unsigned long alignedSizeInBytes (); */
+NS_IMETHODIMP WebGLShortArray::AlignedSizeInBytes(PRUint32 *retval)
+{
+    *retval = mBuffer->capacity;
+    return NS_OK;
+}
+
+/* nsIWebGLArray slice (in unsigned long offset, in unsigned long length); */
+NS_IMETHODIMP WebGLShortArray::Slice(PRUint32 offset, PRUint32 length, nsIWebGLArray **retval)
+{
+    if (length == 0) 
+        return NS_ERROR_FAILURE;
+
+    if (offset + length > mBuffer->capacity)
+        return NS_ERROR_FAILURE;
+
+    nsIWebGLArray *wga = new WebGLShortArray(mBuffer, offset, length);
+    NS_ADDREF(*retval = wga);
+    return NS_OK;
+}
+
+/* [IndexGetter] long get (in unsigned long index); */
+NS_IMETHODIMP WebGLShortArray::Get(PRUint32 index, PRInt32 *retval)
+{
+    if (index >= mLength)
+        return NS_ERROR_FAILURE;
+
+    short *values = static_cast<short*>(mBuffer->data);
+    *retval = values[index];
+
+    return NS_OK;
+}
+
+void
+WebGLShortArray::Set(PRUint32 index, short value)
+{
+    if (index >= mLength)
+        return;
+
+    short *values = static_cast<short*>(mBuffer->data);
+    values[index] = value;
+}
+
+/* void set (); */
+NS_IMETHODIMP WebGLShortArray::Set()
+{
+    NativeJSContext js;
+    if (NS_FAILED(js.error))
+        return js.error;
+
+    if (js.argc < 1 || js.argc > 2)
+        return NS_ERROR_DOM_SYNTAX_ERR;
+
+    if (JSVAL_IS_NUMBER(js.argv[0])) {
+        if (js.argc != 2)
+            return NS_ERROR_DOM_SYNTAX_ERR;
+
+        uint32 index;
+        ::JS_ValueToECMAUint32(js.ctx, js.argv[0], &index);
+
+        int32 value;
+        ::JS_ValueToECMAInt32(js.ctx, js.argv[1], &value);
+
+        if (index >= mLength)
+            return NS_ERROR_FAILURE;
+
+        Set(index, (short) value);
+    } else {
+        return NS_ERROR_NOT_IMPLEMENTED;
+    }
+
+    return NS_OK;
+}
+
+NS_IMETHODIMP_(PRUint32) WebGLShortArray::NativeType()
+{
+    return mBuffer->type;
+}
+
+/* [noscript, notxpcom] voidPtr nativePointer (); */
+NS_IMETHODIMP_(void *) WebGLShortArray::NativePointer()
+{
+    return mBuffer->data;
+}
+
+/* [noscript, notxpcom] unsigned long nativeSize (); */
+NS_IMETHODIMP_(PRUint32) WebGLShortArray::NativeSize()
+{
+    return mBuffer->capacity;
+}
+
+/* [noscript, notxpcom] unsigned long nativeElementSize (); */
+NS_IMETHODIMP_(PRUint32) WebGLShortArray::NativeElementSize()
+{
+    return mBuffer->ElementSize();
+}
+
+/* [noscript, notxpcom] unsigned long nativeCount (); */
+NS_IMETHODIMP_(PRUint32) WebGLShortArray::NativeCount()
+{
+    return mBuffer->length;
+}
+
+// nsIXPCScriptable
+#define XPC_MAP_CLASSNAME WebGLShortArray
+#define XPC_MAP_QUOTED_CLASSNAME "WebGLShortArray"
+#define XPC_MAP_WANT_SETPROPERTY
+#define XPC_MAP_WANT_GETPROPERTY
+#define XPC_MAP_WANT_NEWRESOLVE
+#define XPC_MAP_FLAGS nsIXPCScriptable::USE_JSSTUB_FOR_ADDPROPERTY
+#include "xpc_map_end.h"
+
+PRBool WebGLShortArray::JSValToIndex(JSContext *cx, jsval id, uint32 *retval) {
+    PRBool ok = PR_FALSE;
+    uint32 index;
+
+    if (JSVAL_IS_INT(id)) {
+        index = JSVAL_TO_INT(id);
+        ok = PR_TRUE;
+    } else {
+        ok = JS_ValueToECMAUint32(cx, id, &index);
+    }
+
+    if (!ok || index >= mLength)
+        return PR_FALSE;
+
+    *retval = index;
+    return PR_TRUE;
+}
+
+NS_IMETHODIMP WebGLShortArray::GetProperty(nsIXPConnectWrappedNative *wrapper, JSContext * cx,
+                                           JSObject * obj, jsval id, jsval * vp, PRBool *_retval)
+{
+    uint32 index;
+    
+    if (!JSValToIndex(cx, id, &index)) {
+        *_retval = PR_FALSE;
+        return NS_ERROR_INVALID_ARG;
+    }
+
+    PRInt32 val;
+    Get(index, &val);
+    *_retval = JS_NewNumberValue(cx, val, vp);
+
+    return NS_OK;
+}
+
+NS_IMETHODIMP WebGLShortArray::SetProperty(nsIXPConnectWrappedNative *wrapper, JSContext * cx,
+                                           JSObject * obj, jsval id, jsval * vp, PRBool *_retval)
+{
+    uint32 index;
+    int32 val;
+
+    if (!JSValToIndex(cx, id, &index)) {
+        *_retval = PR_FALSE;
+        return NS_ERROR_INVALID_ARG;
+    }
+
+    PRBool ok = PR_FALSE;
+
+    if (JSVAL_IS_INT(*vp)) {
+        val = JSVAL_TO_INT(*vp);
+        ok = PR_TRUE;
+    } else {
+        ok = JS_ValueToECMAInt32(cx, *vp, &val);
+    }
+
+    if (!ok) {
+        *_retval = PR_FALSE;
+        return NS_ERROR_INVALID_ARG;
+    }
+
+    Set(index, (short) val);
+    return NS_OK;
+}
+
+NS_IMETHODIMP WebGLShortArray::NewResolve(nsIXPConnectWrappedNative *wrapper, JSContext * cx,
+                                          JSObject * obj, jsval id, PRUint32 flags, JSObject * *objp,
+                                          PRBool *_retval)
+{
+    uint32 index;
+    PRBool ok = JSValToIndex(cx, id, &index);
+
+    if (ok) {
+        *_retval = PR_TRUE;
+        *objp = obj;
+    } else {
+        *_retval = PR_FALSE;
+        return NS_ERROR_FAILURE;
+    }
+
+    return NS_OK;
+}
+
+/*
+ * WebGLUnsignedShortArray
+ */
+
+nsresult
+NS_NewWebGLUnsignedShortArray(nsISupports **aResult)
+{
+    nsIWebGLUnsignedShortArray *wgusa = new WebGLUnsignedShortArray();
+    if (!wgusa)
+        return NS_ERROR_OUT_OF_MEMORY;
+
+    NS_ADDREF(*aResult = wgusa);
+    return NS_OK;
+}
+
+WebGLUnsignedShortArray::WebGLUnsignedShortArray(PRUint32 length)
+    : mOffset(0), mLength(length)
+{
+    mBuffer = new WebGLArrayBuffer(length * sizeof(short));
+}
+
+WebGLUnsignedShortArray::WebGLUnsignedShortArray(WebGLArrayBuffer *buffer, PRUint32 offset, PRUint32 length)
+    : mBuffer(buffer), mOffset(offset), mLength(length)
+{
+}
+
+WebGLUnsignedShortArray::WebGLUnsignedShortArray(JSContext *cx, JSObject *arrayObj, jsuint arrayLen)
+    : mOffset(0), mLength(arrayLen)
+{
+    mBuffer = new WebGLArrayBuffer();
+    mBuffer->InitFromJSArray(LOCAL_GL_UNSIGNED_SHORT, 1, cx, arrayObj, arrayLen);
+}
+
+NS_IMETHODIMP
+WebGLUnsignedShortArray::Initialize(nsISupports *owner,
+                                   JSContext *cx,
+                                   JSObject *obj,
+                                   PRUint32 argc,
+                                   jsval *argv)
+{
+    if (JSVAL_IS_NUMBER(argv[0])) {
+        uint32 length;
+        ::JS_ValueToECMAUint32(cx, argv[0], &length);
+        mBuffer = new WebGLArrayBuffer();
+        mBuffer->Prepare(LOCAL_GL_UNSIGNED_SHORT, 1, length);
+        mBuffer->Zero();
+        mLength = length;
+    } else {
+        JSObject *arrayObj;
+        jsuint arrayLen;
+        jsuint byteOffset = 0;
+        jsuint length = 0;
+
+        if (!::JS_ConvertArguments(cx, argc, argv, "o/uu", &arrayObj, &byteOffset, &length) ||
+            arrayObj == NULL)
+        {
+            return NS_ERROR_DOM_SYNTAX_ERR;
+        }
+
+        if (::JS_IsArrayObject(cx, arrayObj) &&
+            ::JS_GetArrayLength(cx, arrayObj, &arrayLen))
+        {
+            mBuffer = new WebGLArrayBuffer();
+            mBuffer->InitFromJSArray(LOCAL_GL_UNSIGNED_SHORT, 1, cx, arrayObj, arrayLen);
+            mLength = arrayLen;
+        } else {
+            nsCOMPtr<nsIWebGLArrayBuffer> canvasObj;
+            nsresult rv;
+            rv = nsContentUtils::XPConnect()->WrapJS(cx, arrayObj, NS_GET_IID(nsIWebGLArrayBuffer), getter_AddRefs(canvasObj));
+            if (NS_FAILED(rv) || !canvasObj) {
+                return NS_ERROR_DOM_SYNTAX_ERR;
+            }
+
+            mBuffer = canvasObj->GetNativeArrayBuffer();
+
+            if (byteOffset % sizeof(short))
+                return NS_ERROR_FAILURE;
+
+            if ((byteOffset + (length * sizeof(short))) > mBuffer->capacity)
+                return NS_ERROR_FAILURE;
+
+            if (length > 0) {
+                mLength = length;
+            } else {
+                if ((mBuffer->capacity - byteOffset) % sizeof(short)) 
+                    return NS_ERROR_FAILURE;
+
+                mLength = (mBuffer->capacity - byteOffset) / sizeof(short);
+            }
+        }
+    }
+
+    return NS_OK;
+}
+
+/* readonly attribute nsIWebGLArrayBuffer buffer; */
+NS_IMETHODIMP WebGLUnsignedShortArray::GetBuffer(nsIWebGLArrayBuffer * *aBuffer)
+{
+    NS_ADDREF(*aBuffer = mBuffer);
+    return NS_OK;
+}
+
+/* readonly attribute unsigned long byteOffset; */
+NS_IMETHODIMP WebGLUnsignedShortArray::GetByteOffset(PRUint32 *aByteOffset)
+{
+    *aByteOffset = mOffset;
+    return NS_OK;
+}
+
+/* readonly attribute unsigned long byteLength; */
+NS_IMETHODIMP WebGLUnsignedShortArray::GetByteLength(PRUint32 *aByteLength)
+{
+    *aByteLength = mLength * sizeof(short);
+    return NS_OK;
+}
+
+/* attribute unsigned long length; */
+NS_IMETHODIMP WebGLUnsignedShortArray::GetLength(PRUint32 *aLength)
+{
+    *aLength = mLength;
+    return NS_OK;
+}
+
+/* unsigned long alignedSizeInBytes (); */
+NS_IMETHODIMP WebGLUnsignedShortArray::AlignedSizeInBytes(PRUint32 *retval)
+{
+    *retval = mBuffer->capacity;
+    return NS_OK;
+}
+
+/* nsIWebGLArray slice (in unsigned long offset, in unsigned long length); */
+NS_IMETHODIMP WebGLUnsignedShortArray::Slice(PRUint32 offset, PRUint32 length, nsIWebGLArray **retval)
+{
+    if (length == 0) 
+        return NS_ERROR_FAILURE;
+
+    if (offset + length > mBuffer->capacity)
+        return NS_ERROR_FAILURE;
+
+    nsIWebGLArray *wga = new WebGLUnsignedShortArray(mBuffer, offset, length);
+    NS_ADDREF(*retval = wga);
+    return NS_OK;
+}
+
+/* [IndexGetter] unsigned long get (in unsigned long index); */
+NS_IMETHODIMP WebGLUnsignedShortArray::Get(PRUint32 index, PRUint32 *retval)
+{
+    if (index >= mLength)
+        return NS_ERROR_FAILURE;
+
+    unsigned short *values = static_cast<unsigned short*>(mBuffer->data);
+    *retval = values[index];
+
+    return NS_OK;
+}
+
+void
+WebGLUnsignedShortArray::Set(PRUint32 index, unsigned short value)
+{
+    if (index >= mLength)
+        return;
+
+    unsigned short *values = static_cast<unsigned short*>(mBuffer->data);
+    values[index] = value;
+}
+
+/* void set (); */
+NS_IMETHODIMP WebGLUnsignedShortArray::Set()
+{
+    NativeJSContext js;
+    if (NS_FAILED(js.error))
+        return js.error;
+
+    if (js.argc < 1 || js.argc > 2)
+        return NS_ERROR_DOM_SYNTAX_ERR;
+
+    if (JSVAL_IS_NUMBER(js.argv[0])) {
+        if (js.argc != 2)
+            return NS_ERROR_DOM_SYNTAX_ERR;
+
+        uint32 index;
+        ::JS_ValueToECMAUint32(js.ctx, js.argv[0], &index);
+
+        uint32 value;
+        ::JS_ValueToECMAUint32(js.ctx, js.argv[1], &value);
+
+        if (index >= mLength)
+            return NS_ERROR_FAILURE;
+
+        Set(index, (unsigned short) value);
+    } else {
+        return NS_ERROR_NOT_IMPLEMENTED;
+    }
+
+    return NS_OK;
+}
+
+NS_IMETHODIMP_(PRUint32) WebGLUnsignedShortArray::NativeType()
+{
+    return mBuffer->type;
+}
+
+/* [noscript, notxpcom] voidPtr nativePointer (); */
+NS_IMETHODIMP_(void *) WebGLUnsignedShortArray::NativePointer()
+{
+    return mBuffer->data;
+}
+
+/* [noscript, notxpcom] unsigned long nativeSize (); */
+NS_IMETHODIMP_(PRUint32) WebGLUnsignedShortArray::NativeSize()
+{
+    return mBuffer->capacity;
+}
+
+/* [noscript, notxpcom] unsigned long nativeElementSize (); */
+NS_IMETHODIMP_(PRUint32) WebGLUnsignedShortArray::NativeElementSize()
+{
+    return mBuffer->ElementSize();
+}
+
+/* [noscript, notxpcom] unsigned long nativeCount (); */
+NS_IMETHODIMP_(PRUint32) WebGLUnsignedShortArray::NativeCount()
+{
+    return mBuffer->length;
+}
+
+// nsIXPCScriptable
+#define XPC_MAP_CLASSNAME WebGLUnsignedShortArray
+#define XPC_MAP_QUOTED_CLASSNAME "WebGLUnsignedShortArray"
+#define XPC_MAP_WANT_SETPROPERTY
+#define XPC_MAP_WANT_GETPROPERTY
+#define XPC_MAP_WANT_NEWRESOLVE
+#define XPC_MAP_FLAGS nsIXPCScriptable::USE_JSSTUB_FOR_ADDPROPERTY
+#include "xpc_map_end.h"
+
+PRBool WebGLUnsignedShortArray::JSValToIndex(JSContext *cx, jsval id, uint32 *retval) {
+    PRBool ok = PR_FALSE;
+    uint32 index;
+
+    if (JSVAL_IS_INT(id)) {
+        index = JSVAL_TO_INT(id);
+        ok = PR_TRUE;
+    } else {
+        ok = JS_ValueToECMAUint32(cx, id, &index);
+    }
+
+    if (!ok || index >= mLength)
+        return PR_FALSE;
+
+    *retval = index;
+    return PR_TRUE;
+}
+
+NS_IMETHODIMP WebGLUnsignedShortArray::GetProperty(nsIXPConnectWrappedNative *wrapper, JSContext * cx,
+                                                   JSObject * obj, jsval id, jsval * vp, PRBool *_retval)
+{
+    uint32 index;
+    
+    if (!JSValToIndex(cx, id, &index)) {
+        *_retval = PR_FALSE;
+        return NS_ERROR_INVALID_ARG;
+    }
+
+    PRUint32 val;
+    Get(index, &val);
+    *_retval = JS_NewNumberValue(cx, val, vp);
+
+    return NS_OK;
+}
+
+NS_IMETHODIMP WebGLUnsignedShortArray::SetProperty(nsIXPConnectWrappedNative *wrapper, JSContext * cx,
+                                                   JSObject * obj, jsval id, jsval * vp, PRBool *_retval)
+{
+    uint32 index;
+    uint32 val;
+
+    if (!JSValToIndex(cx, id, &index)) {
+        *_retval = PR_FALSE;
+        return NS_ERROR_INVALID_ARG;
+    }
+
+    PRBool ok = PR_FALSE;
+
+    if (JSVAL_IS_INT(*vp)) {
+        val = JSVAL_TO_INT(*vp);
+        ok = PR_TRUE;
+    } else {
+        ok = JS_ValueToECMAUint32(cx, *vp, &val);
+    }
+
+    if (!ok) {
+        *_retval = PR_FALSE;
+        return NS_ERROR_INVALID_ARG;
+    }
+
+    Set(index, (unsigned short) val);
+    return NS_OK;
+}
+
+NS_IMETHODIMP WebGLUnsignedShortArray::NewResolve(nsIXPConnectWrappedNative *wrapper, JSContext * cx,
+                                                  JSObject * obj, jsval id, PRUint32 flags, JSObject * *objp,
+                                                  PRBool *_retval)
+{
+    uint32 index;
+    PRBool ok = JSValToIndex(cx, id, &index);
+
+    if (ok) {
+        *_retval = PR_TRUE;
+        *objp = obj;
+    } else {
+        *_retval = PR_FALSE;
+        return NS_ERROR_FAILURE;
+    }
+
+    return NS_OK;
+}
+
+/*
+ * WebGLIntArray
+ */
+
+nsresult
+NS_NewWebGLIntArray(nsISupports **aResult)
+{
+    nsIWebGLIntArray *wgia = new WebGLIntArray();
+    if (!wgia)
+        return NS_ERROR_OUT_OF_MEMORY;
+
+    NS_ADDREF(*aResult = wgia);
+    return NS_OK;
+}
+
+WebGLIntArray::WebGLIntArray(PRUint32 length)
+    : mOffset(0), mLength(length)
+{
+    mBuffer = new WebGLArrayBuffer(length * sizeof(int));
+}
+
+WebGLIntArray::WebGLIntArray(WebGLArrayBuffer *buffer, PRUint32 offset, PRUint32 length)
+    : mBuffer(buffer), mOffset(offset), mLength(length)
+{
+}
+
+WebGLIntArray::WebGLIntArray(JSContext *cx, JSObject *arrayObj, jsuint arrayLen)
+    : mOffset(0), mLength(arrayLen)
+{
+    mBuffer = new WebGLArrayBuffer();
+    mBuffer->InitFromJSArray(LOCAL_GL_INT, 1, cx, arrayObj, arrayLen);
+}
+
+NS_IMETHODIMP
+WebGLIntArray::Initialize(nsISupports *owner,
+                          JSContext *cx,
+                          JSObject *obj,
+                          PRUint32 argc,
+                          jsval *argv)
+{
+    if (JSVAL_IS_NUMBER(argv[0])) {
+        uint32 length;
+        ::JS_ValueToECMAUint32(cx, argv[0], &length);
+        mBuffer = new WebGLArrayBuffer();
+        mBuffer->Prepare(LOCAL_GL_INT, 1, length);
+        mBuffer->Zero();
+        mLength = length;
+    } else {
+        JSObject *arrayObj;
+        jsuint arrayLen;
+        jsuint byteOffset = 0;
+        jsuint length = 0;
+
+        if (!::JS_ConvertArguments(cx, argc, argv, "o/uu", &arrayObj, &byteOffset, &length) ||
+            arrayObj == NULL)
+        {
+            return NS_ERROR_DOM_SYNTAX_ERR;
+        }
+
+        if (::JS_IsArrayObject(cx, arrayObj) &&
+            ::JS_GetArrayLength(cx, arrayObj, &arrayLen))
+        {
+            mBuffer = new WebGLArrayBuffer();
+            mBuffer->InitFromJSArray(LOCAL_GL_INT, 1, cx, arrayObj, arrayLen);
+            mLength = arrayLen;
+        } else {
+            nsCOMPtr<nsIWebGLArrayBuffer> canvasObj;
+            nsresult rv;
+            rv = nsContentUtils::XPConnect()->WrapJS(cx, arrayObj, NS_GET_IID(nsIWebGLArrayBuffer), getter_AddRefs(canvasObj));
+            if (NS_FAILED(rv) || !canvasObj) {
+                return NS_ERROR_DOM_SYNTAX_ERR;
+            }
+
+            mBuffer = canvasObj->GetNativeArrayBuffer();
+
+            if (byteOffset % sizeof(int))
+                return NS_ERROR_FAILURE;
+
+            if ((byteOffset + (length * sizeof(int))) > mBuffer->capacity)
+                return NS_ERROR_FAILURE;
+
+            if (length > 0) {
+                mLength = length;
+            } else {
+                if ((mBuffer->capacity - byteOffset) % sizeof(int))
+                    return NS_ERROR_FAILURE;
+
+                mLength = (mBuffer->capacity - byteOffset) / sizeof(int);
+            }
+        }
+    }
+
+    return NS_OK;
+}
+
+/* readonly attribute nsIWebGLArrayBuffer buffer; */
+NS_IMETHODIMP WebGLIntArray::GetBuffer(nsIWebGLArrayBuffer * *aBuffer)
+{
+    NS_ADDREF(*aBuffer = mBuffer);
+    return NS_OK;
+}
+
+/* readonly attribute unsigned long byteOffset; */
+NS_IMETHODIMP WebGLIntArray::GetByteOffset(PRUint32 *aByteOffset)
+{
+    *aByteOffset = mOffset;
+    return NS_OK;
+}
+
+/* readonly attribute unsigned long byteLength; */
+NS_IMETHODIMP WebGLIntArray::GetByteLength(PRUint32 *aByteLength)
+{
+    *aByteLength = mLength * sizeof(int);
+    return NS_OK;
+}
+
+/* attribute unsigned long length; */
+NS_IMETHODIMP WebGLIntArray::GetLength(PRUint32 *aLength)
+{
+    *aLength = mLength;
+    return NS_OK;
+}
+
+/* unsigned long alignedSizeInBytes (); */
+NS_IMETHODIMP WebGLIntArray::AlignedSizeInBytes(PRUint32 *retval)
+{
+    *retval = mBuffer->capacity;
+    return NS_OK;
+}
+
+/* nsIWebGLArray slice (in unsigned long offset, in unsigned long length); */
+NS_IMETHODIMP WebGLIntArray::Slice(PRUint32 offset, PRUint32 length, nsIWebGLArray **retval)
+{
+    if (length == 0) 
+        return NS_ERROR_FAILURE;
+
+    if (offset + length > mBuffer->capacity)
+        return NS_ERROR_FAILURE;
+
+    nsIWebGLArray *wga = new WebGLIntArray(mBuffer, offset, length);
+    NS_ADDREF(*retval = wga);
+    return NS_OK;
+}
+
+/* [IndexGetter] long get (in unsigned long index); */
+NS_IMETHODIMP WebGLIntArray::Get(PRUint32 index, PRInt32 *retval)
+{
+    if (index >= mLength)
+        return NS_ERROR_FAILURE;
+
+    int *values = static_cast<int*>(mBuffer->data);
+    *retval = values[index];
+
+    return NS_OK;
+}
+
+void
+WebGLIntArray::Set(PRUint32 index, int value)
+{
+    if (index >= mLength)
+        return;
+
+    int *values = static_cast<int*>(mBuffer->data);
+    values[index] = value;
+}
+
+/* void set (); */
+NS_IMETHODIMP WebGLIntArray::Set()
+{
+    NativeJSContext js;
+    if (NS_FAILED(js.error))
+        return js.error;
+
+    if (js.argc < 1 || js.argc > 2)
+        return NS_ERROR_DOM_SYNTAX_ERR;
+
+    if (JSVAL_IS_NUMBER(js.argv[0])) {
+        if (js.argc != 2)
+            return NS_ERROR_DOM_SYNTAX_ERR;
+
+        uint32 index;
+        ::JS_ValueToECMAUint32(js.ctx, js.argv[0], &index);
+
+        int32 value;
+        ::JS_ValueToECMAInt32(js.ctx, js.argv[1], &value);
+
+        if (index >= mLength)
+            return NS_ERROR_FAILURE;
+
+        Set(index, value);
+    } else {
+        return NS_ERROR_NOT_IMPLEMENTED;
+    }
+
+    return NS_OK;
+}
+
+NS_IMETHODIMP_(PRUint32) WebGLIntArray::NativeType()
+{
+    return mBuffer->type;
+}
+
+/* [noscript, notxpcom] voidPtr nativePointer (); */
+NS_IMETHODIMP_(void *) WebGLIntArray::NativePointer()
+{
+    return mBuffer->data;
+}
+
+/* [noscript, notxpcom] unsigned long nativeSize (); */
+NS_IMETHODIMP_(PRUint32) WebGLIntArray::NativeSize()
+{
+    return mBuffer->capacity;
+}
+
+/* [noscript, notxpcom] unsigned long nativeElementSize (); */
+NS_IMETHODIMP_(PRUint32) WebGLIntArray::NativeElementSize()
+{
+    return mBuffer->ElementSize();
+}
+
+/* [noscript, notxpcom] unsigned long nativeCount (); */
+NS_IMETHODIMP_(PRUint32) WebGLIntArray::NativeCount()
+{
+    return mBuffer->length;
+}
+
+// nsIXPCScriptable
+#define XPC_MAP_CLASSNAME WebGLIntArray
+#define XPC_MAP_QUOTED_CLASSNAME "WebGLIntArray"
+#define XPC_MAP_WANT_SETPROPERTY
+#define XPC_MAP_WANT_GETPROPERTY
+#define XPC_MAP_WANT_NEWRESOLVE
+#define XPC_MAP_FLAGS nsIXPCScriptable::USE_JSSTUB_FOR_ADDPROPERTY
+#include "xpc_map_end.h"
+
+PRBool WebGLIntArray::JSValToIndex(JSContext *cx, jsval id, uint32 *retval) {
+    PRBool ok = PR_FALSE;
+    uint32 index;
+
+    if (JSVAL_IS_INT(id)) {
+        index = JSVAL_TO_INT(id);
+        ok = PR_TRUE;
+    } else {
+        ok = JS_ValueToECMAUint32(cx, id, &index);
+    }
+
+    if (!ok || index >= mLength)
+        return PR_FALSE;
+
+    *retval = index;
+    return PR_TRUE;
+}
+
+NS_IMETHODIMP WebGLIntArray::GetProperty(nsIXPConnectWrappedNative *wrapper, JSContext * cx,
+                                         JSObject * obj, jsval id, jsval * vp, PRBool *_retval)
+{
+    uint32 index;
+    
+    if (!JSValToIndex(cx, id, &index)) {
+        *_retval = PR_FALSE;
+        return NS_ERROR_INVALID_ARG;
+    }
+
+    PRInt32 val;
+    Get(index, &val);
+    *_retval = JS_NewNumberValue(cx, val, vp);
+
+    return NS_OK;
+}
+
+NS_IMETHODIMP WebGLIntArray::SetProperty(nsIXPConnectWrappedNative *wrapper, JSContext * cx,
+                                         JSObject * obj, jsval id, jsval * vp, PRBool *_retval)
+{
+    uint32 index;
+    int32 val;
+
+    if (!JSValToIndex(cx, id, &index)) {
+        *_retval = PR_FALSE;
+        return NS_ERROR_INVALID_ARG;
+    }
+
+    PRBool ok = PR_FALSE;
+
+    if (JSVAL_IS_INT(*vp)) {
+        val = JSVAL_TO_INT(*vp);
+        ok = PR_TRUE;
+    } else {
+        ok = JS_ValueToECMAInt32(cx, *vp, &val);
+    }
+
+    if (!ok) {
+        *_retval = PR_FALSE;
+        return NS_ERROR_INVALID_ARG;
+    }
+
+    Set(index, val);
+    return NS_OK;
+}
+
+NS_IMETHODIMP WebGLIntArray::NewResolve(nsIXPConnectWrappedNative *wrapper, JSContext * cx,
+                                        JSObject * obj, jsval id, PRUint32 flags, JSObject * *objp,
+                                        PRBool *_retval)
+{
+    uint32 index;
+    PRBool ok = JSValToIndex(cx, id, &index);
+
+    if (ok) {
+        *_retval = PR_TRUE;
+        *objp = obj;
+    } else {
+        *_retval = PR_FALSE;
+        return NS_ERROR_FAILURE;
+    }
+
+    return NS_OK;
+}
+
+/*
+ * WebGLUnsignedIntArray
+ */
+
+nsresult
+NS_NewWebGLUnsignedIntArray(nsISupports **aResult)
+{
+    nsIWebGLUnsignedIntArray *wguia = new WebGLUnsignedIntArray();
+    if (!wguia)
+        return NS_ERROR_OUT_OF_MEMORY;
+
+    NS_ADDREF(*aResult = wguia);
+    return NS_OK;
+}
+
+WebGLUnsignedIntArray::WebGLUnsignedIntArray(PRUint32 length)
+    : mOffset(0), mLength(length)
+{
+    mBuffer = new WebGLArrayBuffer(length * sizeof(int));
+}
+
+WebGLUnsignedIntArray::WebGLUnsignedIntArray(WebGLArrayBuffer *buffer, PRUint32 offset, PRUint32 length)
+    : mBuffer(buffer), mOffset(offset), mLength(length)
+{
+}
+
+WebGLUnsignedIntArray::WebGLUnsignedIntArray(JSContext *cx, JSObject *arrayObj, jsuint arrayLen)
+    : mOffset(0), mLength(arrayLen)
+{
+    mBuffer = new WebGLArrayBuffer();
+    mBuffer->InitFromJSArray(LOCAL_GL_UNSIGNED_INT, 1, cx, arrayObj, arrayLen);
+}
+
+NS_IMETHODIMP
+WebGLUnsignedIntArray::Initialize(nsISupports *owner,
+                                  JSContext *cx,
+                                  JSObject *obj,
+                                  PRUint32 argc,
+                                  jsval *argv)
+{
+    if (JSVAL_IS_NUMBER(argv[0])) {
+        uint32 length;
+        ::JS_ValueToECMAUint32(cx, argv[0], &length);
+        mBuffer = new WebGLArrayBuffer();
+        mBuffer->Prepare(LOCAL_GL_UNSIGNED_INT, 1, length);
+        mBuffer->Zero();
+        mLength = length;
+    } else {
+        JSObject *arrayObj;
+        jsuint arrayLen;
+        jsuint byteOffset = 0;
+        jsuint length = 0;
+
+        if (!::JS_ConvertArguments(cx, argc, argv, "o/uu", &arrayObj, &byteOffset, &length) ||
+            arrayObj == NULL)
+        {
+            return NS_ERROR_DOM_SYNTAX_ERR;
+        }
+
+        if (::JS_IsArrayObject(cx, arrayObj) &&
+            ::JS_GetArrayLength(cx, arrayObj, &arrayLen))
+        {
+            mBuffer = new WebGLArrayBuffer();
+            mBuffer->InitFromJSArray(LOCAL_GL_UNSIGNED_INT, 1, cx, arrayObj, arrayLen);
+            mLength = arrayLen;
+        } else {
+            nsCOMPtr<nsIWebGLArrayBuffer> canvasObj;
+            nsresult rv;
+            rv = nsContentUtils::XPConnect()->WrapJS(cx, arrayObj, NS_GET_IID(nsIWebGLArrayBuffer), getter_AddRefs(canvasObj));
+            if (NS_FAILED(rv) || !canvasObj) {
+                return NS_ERROR_DOM_SYNTAX_ERR;
+            }
+
+            mBuffer = canvasObj->GetNativeArrayBuffer();
+
+            if (byteOffset % sizeof(int))
+                return NS_ERROR_FAILURE;
+
+            if ((byteOffset + (length * sizeof(int))) > mBuffer->capacity)
+                return NS_ERROR_FAILURE;
+
+            if (length > 0) {
+                mLength = length;
+            } else {
+                if ((mBuffer->capacity - byteOffset) % sizeof(int))
+                    return NS_ERROR_FAILURE;
+
+                mLength = (mBuffer->capacity - byteOffset) / sizeof(int);
+            }
+        }
+    }
+
+    return NS_OK;
+}
+
+/* readonly attribute nsIWebGLArrayBuffer buffer; */
+NS_IMETHODIMP WebGLUnsignedIntArray::GetBuffer(nsIWebGLArrayBuffer * *aBuffer)
+{
+    NS_ADDREF(*aBuffer = mBuffer);
+    return NS_OK;
+}
+
+/* readonly attribute unsigned long byteOffset; */
+NS_IMETHODIMP WebGLUnsignedIntArray::GetByteOffset(PRUint32 *aByteOffset)
+{
+    *aByteOffset = mOffset;
+    return NS_OK;
+}
+
+/* readonly attribute unsigned long byteLength; */
+NS_IMETHODIMP WebGLUnsignedIntArray::GetByteLength(PRUint32 *aByteLength)
+{
+    *aByteLength = mLength * sizeof(int);
+    return NS_OK;
+}
+
+/* attribute unsigned long length; */
+NS_IMETHODIMP WebGLUnsignedIntArray::GetLength(PRUint32 *aLength)
+{
+    *aLength = mLength;
+    return NS_OK;
+}
+
+/* unsigned long alignedSizeInBytes (); */
+NS_IMETHODIMP WebGLUnsignedIntArray::AlignedSizeInBytes(PRUint32 *retval)
+{
+    *retval = mBuffer->capacity;
+    return NS_OK;
+}
+
+/* nsIWebGLArray slice (in unsigned long offset, in unsigned long length); */
+NS_IMETHODIMP WebGLUnsignedIntArray::Slice(PRUint32 offset, PRUint32 length, nsIWebGLArray **retval)
+{
+    if (length == 0) 
+        return NS_ERROR_FAILURE;
+
+    if (offset + length > mBuffer->capacity)
+        return NS_ERROR_FAILURE;
+
+    nsIWebGLArray *wga = new WebGLUnsignedIntArray(mBuffer, offset, length);
+    NS_ADDREF(*retval = wga);
+    return NS_OK;
+}
+
+/* [IndexGetter] unsigned long get (in unsigned long index); */
+NS_IMETHODIMP WebGLUnsignedIntArray::Get(PRUint32 index, PRUint32 *retval)
+{
+    if (index >= mLength)
+        return NS_ERROR_FAILURE;
+
+    unsigned int *values = static_cast<unsigned int*>(mBuffer->data);
+    *retval = values[index];
+
+    return NS_OK;
+}
+
+void
+WebGLUnsignedIntArray::Set(PRUint32 index, unsigned int value)
+{
+    if (index >= mLength)
+        return;
+
+    unsigned int *values = static_cast<unsigned int*>(mBuffer->data);
+    values[index] = value;
+}
+
+/* void set (); */
+NS_IMETHODIMP WebGLUnsignedIntArray::Set()
+{
+    NativeJSContext js;
+    if (NS_FAILED(js.error))
+        return js.error;
+
+    if (js.argc < 1 || js.argc > 2)
+        return NS_ERROR_DOM_SYNTAX_ERR;
+
+    if (JSVAL_IS_NUMBER(js.argv[0])) {
+        if (js.argc != 2)
+            return NS_ERROR_DOM_SYNTAX_ERR;
+
+        uint32 index;
+        ::JS_ValueToECMAUint32(js.ctx, js.argv[0], &index);
+
+        uint32 value;
+        ::JS_ValueToECMAUint32(js.ctx, js.argv[1], &value);
+
+        if (index >= mLength)
+            return NS_ERROR_FAILURE;
+
+        Set(index, value);
+    } else {
+        return NS_ERROR_NOT_IMPLEMENTED;
+    }
+
+    return NS_OK;
+}
+
+NS_IMETHODIMP_(PRUint32) WebGLUnsignedIntArray::NativeType()
+{
+    return mBuffer->type;
+}
+
+/* [noscript, notxpcom] voidPtr nativePointer (); */
+NS_IMETHODIMP_(void *) WebGLUnsignedIntArray::NativePointer()
+{
+    return mBuffer->data;
+}
+
+/* [noscript, notxpcom] unsigned long nativeSize (); */
+NS_IMETHODIMP_(PRUint32) WebGLUnsignedIntArray::NativeSize()
+{
+    return mBuffer->capacity;
+}
+
+/* [noscript, notxpcom] unsigned long nativeElementSize (); */
+NS_IMETHODIMP_(PRUint32) WebGLUnsignedIntArray::NativeElementSize()
+{
+    return mBuffer->ElementSize();
+}
+
+/* [noscript, notxpcom] unsigned long nativeCount (); */
+NS_IMETHODIMP_(PRUint32) WebGLUnsignedIntArray::NativeCount()
+{
+    return mBuffer->length;
+}
+
+// nsIXPCScriptable
+#define XPC_MAP_CLASSNAME WebGLUnsignedIntArray
+#define XPC_MAP_QUOTED_CLASSNAME "WebGLUnsignedIntArray"
+#define XPC_MAP_WANT_SETPROPERTY
+#define XPC_MAP_WANT_GETPROPERTY
+#define XPC_MAP_WANT_NEWRESOLVE
+#define XPC_MAP_FLAGS nsIXPCScriptable::USE_JSSTUB_FOR_ADDPROPERTY
+#include "xpc_map_end.h"
+
+PRBool WebGLUnsignedIntArray::JSValToIndex(JSContext *cx, jsval id, uint32 *retval) {
+    PRBool ok = PR_FALSE;
+    uint32 index;
+
+    if (JSVAL_IS_INT(id)) {
+        index = JSVAL_TO_INT(id);
+        ok = PR_TRUE;
+    } else {
+        ok = JS_ValueToECMAUint32(cx, id, &index);
+    }
+
+    if (!ok || index >= mLength)
+        return PR_FALSE;
+
+    *retval = index;
+    return PR_TRUE;
+}
+
+NS_IMETHODIMP WebGLUnsignedIntArray::GetProperty(nsIXPConnectWrappedNative *wrapper, JSContext * cx,
+                                                 JSObject * obj, jsval id, jsval * vp, PRBool *_retval)
+{
+    uint32 index;
+    
+    if (!JSValToIndex(cx, id, &index)) {
+        *_retval = PR_FALSE;
+        return NS_ERROR_INVALID_ARG;
+    }
+
+    PRUint32 val;
+    Get(index, &val);
+    *_retval = JS_NewNumberValue(cx, val, vp);
+
+    return NS_OK;
+}
+
+NS_IMETHODIMP WebGLUnsignedIntArray::SetProperty(nsIXPConnectWrappedNative *wrapper, JSContext * cx,
+                                                 JSObject * obj, jsval id, jsval * vp, PRBool *_retval)
+{
+    uint32 index;
+    uint32 val;
+
+    if (!JSValToIndex(cx, id, &index)) {
+        *_retval = PR_FALSE;
+        return NS_ERROR_INVALID_ARG;
+    }
+
+    PRBool ok = PR_FALSE;
+
+    if (JSVAL_IS_INT(*vp)) {
+        val = JSVAL_TO_INT(*vp);
+        ok = PR_TRUE;
+    } else {
+        ok = JS_ValueToECMAUint32(cx, *vp, &val);
+    }
+
+    if (!ok) {
+        *_retval = PR_FALSE;
+        return NS_ERROR_INVALID_ARG;
+    }
+
+    Set(index, val);
+    return NS_OK;
+}
+
+NS_IMETHODIMP WebGLUnsignedIntArray::NewResolve(nsIXPConnectWrappedNative *wrapper, JSContext * cx,
+                                                JSObject * obj, jsval id, PRUint32 flags, JSObject * *objp,
+                                                PRBool *_retval)
+{
+    uint32 index;
+    PRBool ok = JSValToIndex(cx, id, &index);
+
+    if (ok) {
+        *_retval = PR_TRUE;
+        *objp = obj;
+    } else {
+        *_retval = PR_FALSE;
+        return NS_ERROR_FAILURE;
+    }
+
+    return NS_OK;
+}
+
+
+/*
+ * XPCOM AddRef/Release/QI
+ */
+NS_IMPL_ADDREF(WebGLArrayBuffer)
+NS_IMPL_RELEASE(WebGLArrayBuffer)
+
+NS_INTERFACE_MAP_BEGIN(WebGLArrayBuffer)
+  NS_INTERFACE_MAP_ENTRY(nsIWebGLArrayBuffer)
+  NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIWebGLArrayBuffer)
+  NS_INTERFACE_MAP_ENTRY(nsIJSNativeInitializer)
+  NS_INTERFACE_MAP_ENTRY_CONTENT_CLASSINFO(WebGLArrayBuffer)
+NS_INTERFACE_MAP_END
+
+NS_IMPL_ADDREF(WebGLFloatArray)
+NS_IMPL_RELEASE(WebGLFloatArray)
+
+NS_INTERFACE_MAP_BEGIN(WebGLFloatArray)
+  NS_INTERFACE_MAP_ENTRY(nsIWebGLArray)
+  NS_INTERFACE_MAP_ENTRY(nsIWebGLFloatArray)
+  NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIWebGLFloatArray)
+  NS_INTERFACE_MAP_ENTRY(nsIJSNativeInitializer)
+  NS_INTERFACE_MAP_ENTRY(nsIXPCScriptable)
+  NS_INTERFACE_MAP_ENTRY_CONTENT_CLASSINFO(WebGLFloatArray)
+NS_INTERFACE_MAP_END
+
+NS_IMPL_ADDREF(WebGLByteArray)
+NS_IMPL_RELEASE(WebGLByteArray)
+
+NS_INTERFACE_MAP_BEGIN(WebGLByteArray)
+  NS_INTERFACE_MAP_ENTRY(nsIWebGLArray)
+  NS_INTERFACE_MAP_ENTRY(nsIWebGLByteArray)
+  NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIWebGLByteArray)
+  NS_INTERFACE_MAP_ENTRY(nsIJSNativeInitializer)
+  NS_INTERFACE_MAP_ENTRY(nsIXPCScriptable)
+  NS_INTERFACE_MAP_ENTRY_CONTENT_CLASSINFO(WebGLByteArray)
+NS_INTERFACE_MAP_END
+
+NS_IMPL_ADDREF(WebGLUnsignedByteArray)
+NS_IMPL_RELEASE(WebGLUnsignedByteArray)
+
+NS_INTERFACE_MAP_BEGIN(WebGLUnsignedByteArray)
+  NS_INTERFACE_MAP_ENTRY(nsIWebGLArray)
+  NS_INTERFACE_MAP_ENTRY(nsIWebGLUnsignedByteArray)
+  NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIWebGLUnsignedByteArray)
+  NS_INTERFACE_MAP_ENTRY(nsIJSNativeInitializer)
+  NS_INTERFACE_MAP_ENTRY(nsIXPCScriptable)
+  NS_INTERFACE_MAP_ENTRY_CONTENT_CLASSINFO(WebGLUnsignedByteArray)
+NS_INTERFACE_MAP_END
+
+NS_IMPL_ADDREF(WebGLShortArray)
+NS_IMPL_RELEASE(WebGLShortArray)
+
+NS_INTERFACE_MAP_BEGIN(WebGLShortArray)
+  NS_INTERFACE_MAP_ENTRY(nsIWebGLArray)
+  NS_INTERFACE_MAP_ENTRY(nsIWebGLShortArray)
+  NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIWebGLShortArray)
+  NS_INTERFACE_MAP_ENTRY(nsIJSNativeInitializer)
+  NS_INTERFACE_MAP_ENTRY(nsIXPCScriptable)
+  NS_INTERFACE_MAP_ENTRY_CONTENT_CLASSINFO(WebGLShortArray)
+NS_INTERFACE_MAP_END
+
+NS_IMPL_ADDREF(WebGLUnsignedShortArray)
+NS_IMPL_RELEASE(WebGLUnsignedShortArray)
+
+NS_INTERFACE_MAP_BEGIN(WebGLUnsignedShortArray)
+  NS_INTERFACE_MAP_ENTRY(nsIWebGLArray)
+  NS_INTERFACE_MAP_ENTRY(nsIWebGLUnsignedShortArray)
+  NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIWebGLUnsignedShortArray)
+  NS_INTERFACE_MAP_ENTRY(nsIJSNativeInitializer)
+  NS_INTERFACE_MAP_ENTRY(nsIXPCScriptable)
+  NS_INTERFACE_MAP_ENTRY_CONTENT_CLASSINFO(WebGLUnsignedShortArray)
+NS_INTERFACE_MAP_END
+
+NS_IMPL_ADDREF(WebGLIntArray)
+NS_IMPL_RELEASE(WebGLIntArray)
+
+NS_INTERFACE_MAP_BEGIN(WebGLIntArray)
+  NS_INTERFACE_MAP_ENTRY(nsIWebGLArray)
+  NS_INTERFACE_MAP_ENTRY(nsIWebGLIntArray)
+  NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIWebGLIntArray)
+  NS_INTERFACE_MAP_ENTRY(nsIJSNativeInitializer)
+  NS_INTERFACE_MAP_ENTRY(nsIXPCScriptable)
+  NS_INTERFACE_MAP_ENTRY_CONTENT_CLASSINFO(WebGLIntArray)
+NS_INTERFACE_MAP_END
+
+NS_IMPL_ADDREF(WebGLUnsignedIntArray)
+NS_IMPL_RELEASE(WebGLUnsignedIntArray)
+
+NS_INTERFACE_MAP_BEGIN(WebGLUnsignedIntArray)
+  NS_INTERFACE_MAP_ENTRY(nsIWebGLArray)
+  NS_INTERFACE_MAP_ENTRY(nsIWebGLUnsignedIntArray)
+  NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIWebGLUnsignedIntArray)
+  NS_INTERFACE_MAP_ENTRY(nsIJSNativeInitializer)
+  NS_INTERFACE_MAP_ENTRY(nsIXPCScriptable)
+  NS_INTERFACE_MAP_ENTRY_CONTENT_CLASSINFO(WebGLUnsignedIntArray)
+NS_INTERFACE_MAP_END
new file mode 100644
--- /dev/null
+++ b/content/canvas/src/WebGLArrays.h
@@ -0,0 +1,344 @@
+/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is mozilla.org code.
+ *
+ * The Initial Developer of the Original Code is
+ *   Mozilla Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 2009
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   Mark Steele <mwsteele@gmail.com>
+ *   Vladimir Vukicevic <vladimir@pobox.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#ifndef WEBGLARRAYS_H_
+#define WEBGLARRAYS_H_
+
+#include <stdarg.h>
+
+#include "nsTArray.h"
+#include "nsDataHashtable.h"
+#include "nsRefPtrHashtable.h"
+#include "nsHashKeys.h"
+
+#include "nsICanvasRenderingContextWebGL.h"
+#include "nsICanvasRenderingContextInternal.h"
+#include "nsIJSNativeInitializer.h"
+#include "nsIXPCScriptable.h"
+
+#include "SimpleBuffer.h"
+
+namespace mozilla {
+
+//
+// array wrapper classes
+//
+
+// XXX refactor buffer stuff
+class WebGLArrayBuffer :
+    public nsIWebGLArrayBuffer,
+    public nsIJSNativeInitializer,
+    public SimpleBuffer
+{
+public:
+
+    WebGLArrayBuffer() { }
+    WebGLArrayBuffer(PRUint32 length);
+
+    NS_DECL_ISUPPORTS
+    NS_DECL_NSIWEBGLARRAYBUFFER
+
+    NS_IMETHOD Initialize(nsISupports* aOwner,
+                          JSContext* aCx,
+                          JSObject* aObj,
+                          PRUint32 aArgc,
+                          jsval* aArgv);
+};
+
+class WebGLArray
+{
+    
+};
+
+class WebGLFloatArray :
+    public nsIXPCScriptable,
+    public nsIWebGLFloatArray,
+    public nsIJSNativeInitializer
+{
+public:
+    WebGLFloatArray() :
+        mOffset(0), mLength(0) { }
+
+    WebGLFloatArray(PRUint32 length);
+    WebGLFloatArray(WebGLArrayBuffer *buffer, PRUint32 offset, PRUint32 length);
+    WebGLFloatArray(JSContext *cx, JSObject *arrayObj, jsuint arrayLen);
+
+    NS_DECL_ISUPPORTS
+    NS_DECL_NSIWEBGLARRAY
+    NS_DECL_NSIWEBGLFLOATARRAY
+    NS_DECL_NSIXPCSCRIPTABLE
+
+    NS_IMETHOD Initialize(nsISupports* aOwner,
+                          JSContext* aCx,
+                          JSObject* aObj,
+                          PRUint32 aArgc,
+                          jsval* aArgv);
+
+    void Set(PRUint32 index, float value);
+    PRBool JSValToIndex(JSContext *cx, jsval id, uint32 *retval);
+
+protected:
+    nsRefPtr<WebGLArrayBuffer> mBuffer;
+    PRUint32 mOffset;
+    PRUint32 mLength;
+    PRUint32 mSize;
+    PRUint32 mElementSize;
+    PRUint32 mCount;
+};
+
+class WebGLByteArray :
+    public nsIXPCScriptable,
+    public nsIWebGLByteArray,
+    public nsIJSNativeInitializer
+{
+public:
+    WebGLByteArray() :
+        mOffset(0), mLength(0) { }
+
+    WebGLByteArray(PRUint32 length);
+    WebGLByteArray(WebGLArrayBuffer *buffer, PRUint32 offset, PRUint32 length);
+    WebGLByteArray(JSContext *cx, JSObject *arrayObj, jsuint arrayLen);
+
+    NS_DECL_ISUPPORTS
+    NS_DECL_NSIWEBGLARRAY
+    NS_DECL_NSIWEBGLBYTEARRAY
+    NS_DECL_NSIXPCSCRIPTABLE
+
+    NS_IMETHOD Initialize(nsISupports* aOwner,
+                          JSContext* aCx,
+                          JSObject* aObj,
+                          PRUint32 aArgc,
+                          jsval* aArgv);
+
+    void Set(PRUint32 index, char value);
+    PRBool JSValToIndex(JSContext *cx, jsval id, uint32 *retval);
+
+protected:
+    nsRefPtr<WebGLArrayBuffer> mBuffer;
+    PRUint32 mOffset;
+    PRUint32 mLength;
+    PRUint32 mSize;
+    PRUint32 mElementSize;
+    PRUint32 mCount;
+};
+
+class WebGLUnsignedByteArray :
+    public nsIXPCScriptable,
+    public nsIWebGLUnsignedByteArray,
+    public nsIJSNativeInitializer
+{
+public:
+    WebGLUnsignedByteArray() :
+        mOffset(0), mLength(0) { }
+
+    WebGLUnsignedByteArray(PRUint32 length);
+    WebGLUnsignedByteArray(WebGLArrayBuffer *buffer, PRUint32 offset, PRUint32 length);
+    WebGLUnsignedByteArray(JSContext *cx, JSObject *arrayObj, jsuint arrayLen);
+
+    NS_DECL_ISUPPORTS
+    NS_DECL_NSIWEBGLARRAY
+    NS_DECL_NSIWEBGLUNSIGNEDBYTEARRAY
+    NS_DECL_NSIXPCSCRIPTABLE
+
+    NS_IMETHOD Initialize(nsISupports* aOwner,
+                          JSContext* aCx,
+                          JSObject* aObj,
+                          PRUint32 aArgc,
+                          jsval* aArgv);
+
+    void Set(PRUint32 index, unsigned char value);
+    PRBool JSValToIndex(JSContext *cx, jsval id, uint32 *retval);
+
+protected:
+    nsRefPtr<WebGLArrayBuffer> mBuffer;
+    PRUint32 mOffset;
+    PRUint32 mLength;
+    PRUint32 mSize;
+    PRUint32 mElementSize;
+    PRUint32 mCount;
+};
+
+class WebGLShortArray :
+    public nsIXPCScriptable,
+    public nsIWebGLShortArray,
+    public nsIJSNativeInitializer
+{
+public:
+    WebGLShortArray() :
+        mOffset(0), mLength(0) { }
+
+    WebGLShortArray(PRUint32 length);
+    WebGLShortArray(WebGLArrayBuffer *buffer, PRUint32 offset, PRUint32 length);
+    WebGLShortArray(JSContext *cx, JSObject *arrayObj, jsuint arrayLen);
+
+    NS_DECL_ISUPPORTS
+    NS_DECL_NSIWEBGLARRAY
+    NS_DECL_NSIWEBGLSHORTARRAY
+    NS_DECL_NSIXPCSCRIPTABLE
+
+    NS_IMETHOD Initialize(nsISupports* aOwner,
+                          JSContext* aCx,
+                          JSObject* aObj,
+                          PRUint32 aArgc,
+                          jsval* aArgv);
+
+    void Set(PRUint32 index, short value);
+    PRBool JSValToIndex(JSContext *cx, jsval id, uint32 *retval);
+
+protected:
+    nsRefPtr<WebGLArrayBuffer> mBuffer;
+    PRUint32 mOffset;
+    PRUint32 mLength;
+    PRUint32 mSize;
+    PRUint32 mElementSize;
+    PRUint32 mCount;
+};
+
+class WebGLUnsignedShortArray :
+    public nsIXPCScriptable,
+    public nsIWebGLUnsignedShortArray,
+    public nsIJSNativeInitializer
+{
+public:
+    WebGLUnsignedShortArray() :
+        mOffset(0), mLength(0) { }
+
+    WebGLUnsignedShortArray(PRUint32 length);
+    WebGLUnsignedShortArray(WebGLArrayBuffer *buffer, PRUint32 offset, PRUint32 length);
+    WebGLUnsignedShortArray(JSContext *cx, JSObject *arrayObj, jsuint arrayLen);
+
+    NS_DECL_ISUPPORTS
+    NS_DECL_NSIWEBGLARRAY
+    NS_DECL_NSIWEBGLUNSIGNEDSHORTARRAY
+    NS_DECL_NSIXPCSCRIPTABLE
+
+    NS_IMETHOD Initialize(nsISupports* aOwner,
+                          JSContext* aCx,
+                          JSObject* aObj,
+                          PRUint32 aArgc,
+                          jsval* aArgv);
+
+    void Set(PRUint32 index, unsigned short value);
+    PRBool JSValToIndex(JSContext *cx, jsval id, uint32 *retval);
+
+protected:
+    nsRefPtr<WebGLArrayBuffer> mBuffer;
+    PRUint32 mOffset;
+    PRUint32 mLength;
+    PRUint32 mSize;
+    PRUint32 mElementSize;
+    PRUint32 mCount;
+};
+
+class WebGLIntArray :
+    public nsIXPCScriptable,
+    public nsIWebGLIntArray,
+    public nsIJSNativeInitializer
+{
+public:
+    WebGLIntArray() :
+        mOffset(0), mLength(0) { }
+
+    WebGLIntArray(PRUint32 length);
+    WebGLIntArray(WebGLArrayBuffer *buffer, PRUint32 offset, PRUint32 length);
+    WebGLIntArray(JSContext *cx, JSObject *arrayObj, jsuint arrayLen);
+
+    NS_DECL_ISUPPORTS
+    NS_DECL_NSIWEBGLARRAY
+    NS_DECL_NSIWEBGLINTARRAY
+    NS_DECL_NSIXPCSCRIPTABLE
+
+    NS_IMETHOD Initialize(nsISupports* aOwner,
+                          JSContext* aCx,
+                          JSObject* aObj,
+                          PRUint32 aArgc,
+                          jsval* aArgv);
+
+    void Set(PRUint32 index, int value);
+    PRBool JSValToIndex(JSContext *cx, jsval id, uint32 *retval);
+
+protected:
+    nsRefPtr<WebGLArrayBuffer> mBuffer;
+    PRUint32 mOffset;
+    PRUint32 mLength;
+    PRUint32 mSize;
+    PRUint32 mElementSize;
+    PRUint32 mCount;
+};
+
+class WebGLUnsignedIntArray :
+    public nsIXPCScriptable,
+    public nsIWebGLUnsignedIntArray,
+    public nsIJSNativeInitializer
+{
+public:
+    WebGLUnsignedIntArray() :
+        mOffset(0), mLength(0) { }
+
+    WebGLUnsignedIntArray(PRUint32 length);
+    WebGLUnsignedIntArray(WebGLArrayBuffer *buffer, PRUint32 offset, PRUint32 length);
+    WebGLUnsignedIntArray(JSContext *cx, JSObject *arrayObj, jsuint arrayLen);
+
+    NS_DECL_ISUPPORTS
+    NS_DECL_NSIWEBGLARRAY
+    NS_DECL_NSIWEBGLUNSIGNEDINTARRAY
+    NS_DECL_NSIXPCSCRIPTABLE
+
+    NS_IMETHOD Initialize(nsISupports* aOwner,
+                          JSContext* aCx,
+                          JSObject* aObj,
+                          PRUint32 aArgc,
+                          jsval* aArgv);
+
+    void Set(PRUint32 index, unsigned int value);
+    PRBool JSValToIndex(JSContext *cx, jsval id, uint32 *retval);
+
+protected:
+    nsRefPtr<WebGLArrayBuffer> mBuffer;
+    PRUint32 mOffset;
+    PRUint32 mLength;
+    PRUint32 mSize;
+    PRUint32 mElementSize;
+    PRUint32 mCount;
+};
+
+} /* namespace mozilla */
+
+
+#endif /* WEBGLARRAYS_H_ */
--- a/content/canvas/src/WebGLContext.cpp
+++ b/content/canvas/src/WebGLContext.cpp
@@ -7,18 +7,16 @@
 #include "nsIClassInfoImpl.h"
 #include "nsContentUtils.h"
 #include "nsIXPConnect.h"
 #include "nsDOMError.h"
 
 #include "gfxContext.h"
 #include "gfxPattern.h"
 
-#include "localgl.h"
-
 #include "CanvasUtils.h"
 #include "NativeJSContext.h"
 
 using namespace mozilla;
 
 nsresult NS_NewCanvasRenderingContextWebGL(nsICanvasRenderingContextWebGL** aResult);
 
 nsresult
--- a/content/canvas/src/WebGLContext.h
+++ b/content/canvas/src/WebGLContext.h
@@ -50,20 +50,19 @@
 #include "nsIDocShell.h"
 
 #include "nsICanvasRenderingContextWebGL.h"
 #include "nsICanvasRenderingContextInternal.h"
 #include "nsWeakReference.h"
 #include "nsIDOMHTMLElement.h"
 #include "nsIJSNativeInitializer.h"
 
+#include "SimpleBuffer.h"
 #include "nsGLPbuffer.h"
 
-#include "localgl.h"
-
 class nsIDocShell;
 
 namespace mozilla {
 
 class WebGLTexture;
 class WebGLBuffer;
 class WebGLProgram;
 class WebGLShader;
--- a/content/canvas/src/WebGLContextGL.cpp
+++ b/content/canvas/src/WebGLContextGL.cpp
@@ -47,16 +47,17 @@
 //#include "nsIDOMHTMLCanvasElement.h"
 
 #include "nsContentUtils.h"
 #include "nsDOMError.h"
 #include "nsLayoutUtils.h"
 
 #include "CanvasUtils.h"
 #include "NativeJSContext.h"
+#include "SimpleBuffer.h"
 
 #include "jstypedarray.h"
 
 using namespace mozilla;
 
 // XXX why is this broken?
 #ifndef GL_BLEND_EQUATION
 #define GL_BLEND_EQUATION 0x8009
@@ -2399,17 +2400,17 @@ WebGLContext::ValidateGL()
 
     mAttribBuffers.SetLength(val);
 
     //fprintf(stderr, "GL_MAX_VERTEX_ATTRIBS: %d\n", val);
 
     // Note: GL_MAX_TEXTURE_UNITS is fixed at 4 for most desktop hardware,
     // even though the hardware supports much more.  The
     // GL_MAX_{COMBINED_}TEXTURE_IMAGE_UNITS value is the accurate
-    // value.  For GLES2, GL_MAX_TEXTURE_UNITS is still correct.
+    // value.  For GLES2, GL_MAX_TEXTURE_UNITS is still correc.t
     gl->fGetIntegerv(LOCAL_GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, &val);
     if (val == 0) {
         LogMessage("GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS is 0!");
         return PR_FALSE;
     }
 
     mBound2DTextures.SetLength(val);
     mBoundCubeMapTextures.SetLength(val);
--- a/content/canvas/src/localgl.h
+++ b/content/canvas/src/localgl.h
@@ -31,21 +31,19 @@
  * use your version of this file under the terms of the MPL, indicate your
  * decision by deleting the provisions above and replace them with the notice
  * and other provisions required by the GPL or the LGPL. If you do not delete
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
-#if !defined(LOCALGL_H_)
+#if !defined(LOCALGL_H_) && !defined(__gl_h_)
 
 #define LOCALGL_H_
-
-#if !defined(__gl_h_)
 #define __gl_h_
 
 #if defined(__APPLE__XXX)
 typedef unsigned long GLenum;
 typedef unsigned long GLbitfield;
 typedef unsigned long GLuint;
 typedef long GLint;
 typedef long GLsizei;
@@ -63,31 +61,29 @@ typedef unsigned char GLubyte;
 typedef unsigned short GLushort;
 typedef float GLfloat;
 typedef float GLclampf;
 typedef double GLdouble;
 typedef double GLclampd;
 typedef void GLvoid;
 
 typedef char GLchar;
-typedef ptrdiff_t GLsizeiptr;
-typedef ptrdiff_t GLintptr;
+typedef PRInt32 GLsizeiptr;
+typedef PRInt32 GLintptr;
 
 #ifndef GLAPIENTRY
 # ifdef WIN32
 #  define GLAPIENTRY APIENTRY
 #  define GLAPI
 # else
 #  define GLAPIENTRY
 #  define GLAPI
 # endif
 #endif
 
-#endif /* __gl_h_ */
-
 #define LOCAL_GL_VERSION_1_1 1
 #define LOCAL_GL_ACCUM 0x0100
 #define LOCAL_GL_LOAD 0x0101
 #define LOCAL_GL_RETURN 0x0102
 #define LOCAL_GL_MULT 0x0103
 #define LOCAL_GL_ADD 0x0104
 #define LOCAL_GL_NEVER 0x0200
 #define LOCAL_GL_LESS 0x0201
@@ -844,17 +840,19 @@ typedef ptrdiff_t GLintptr;
 #define LOCAL_GL_STATIC_DRAW 0x88E4
 #define LOCAL_GL_STATIC_READ 0x88E5
 #define LOCAL_GL_STATIC_COPY 0x88E6
 #define LOCAL_GL_DYNAMIC_DRAW 0x88E8
 #define LOCAL_GL_DYNAMIC_READ 0x88E9
 #define LOCAL_GL_DYNAMIC_COPY 0x88EA
 #define LOCAL_GL_SAMPLES_PASSED 0x8914
 #define LOCAL_GL_VERSION_2_0 1
-#define LOCAL_GL_BLEND_EQUATION_RGB 0x8009
+#ifndef GL_BLEND_EQUATION_RGB
+#define LOCAL_GL_BLEND_EQUATION_RGB GL_BLEND_EQUATION
+#endif
 #define LOCAL_GL_VERTEX_ATTRIB_ARRAY_ENABLED 0x8622
 #define LOCAL_GL_VERTEX_ATTRIB_ARRAY_SIZE 0x8623
 #define LOCAL_GL_VERTEX_ATTRIB_ARRAY_STRIDE 0x8624
 #define LOCAL_GL_VERTEX_ATTRIB_ARRAY_TYPE 0x8625
 #define LOCAL_GL_CURRENT_VERTEX_ATTRIB 0x8626
 #define LOCAL_GL_VERTEX_PROGRAM_POINT_SIZE 0x8642
 #define LOCAL_GL_VERTEX_PROGRAM_TWO_SIDE 0x8643
 #define LOCAL_GL_VERTEX_ATTRIB_ARRAY_POINTER 0x8645
new file mode 100644
--- /dev/null
+++ b/dom/interfaces/canvas/nsICanvasRenderingContextGL.idl
@@ -0,0 +1,357 @@
+/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is canvas 3D.
+ *
+ * The Initial Developer of the Original Code is
+ *   Mozilla Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 2007
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   Vladimir Vukicevic <vladimir@pobox.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+
+#include "nsISupports.idl"
+
+interface nsIDOMHTMLCanvasElement;
+
+[scriptable, uuid(0f3d8dae-7d43-490b-93e9-5ff908ac6ff5)]
+interface nsICanvasRenderingContextGL : nsISupports
+{
+  readonly attribute nsIDOMHTMLCanvasElement canvas;
+
+  /**
+   ** GL constants
+   **/
+  const PRUint32 DEPTH_BUFFER_BIT        = 0x00000100;
+  const PRUint32 STENCIL_BUFFER_BIT      = 0x00000400;
+  const PRUint32 COLOR_BUFFER_BIT        = 0x00004000;
+  const PRUint32 POINTS                  = 0x0000;
+  const PRUint32 LINES                   = 0x0001;
+  const PRUint32 LINE_LOOP               = 0x0002;
+  const PRUint32 LINE_STRIP              = 0x0003;
+  const PRUint32 TRIANGLES               = 0x0004;
+  const PRUint32 TRIANGLE_STRIP          = 0x0005;
+  const PRUint32 TRIANGLE_FAN            = 0x0006;
+  const PRUint32 ZERO                    = 0;
+  const PRUint32 ONE                     = 1;
+  const PRUint32 SRC_COLOR               = 0x0300;
+  const PRUint32 ONE_MINUS_SRC_COLOR     = 0x0301;
+  const PRUint32 SRC_ALPHA               = 0x0302;
+  const PRUint32 ONE_MINUS_SRC_ALPHA     = 0x0303;
+  const PRUint32 DST_ALPHA               = 0x0304;
+  const PRUint32 ONE_MINUS_DST_ALPHA     = 0x0305;
+  const PRUint32 DST_COLOR               = 0x0306;
+  const PRUint32 ONE_MINUS_DST_COLOR     = 0x0307;
+  const PRUint32 SRC_ALPHA_SATURATE      = 0x0308;
+  const PRUint32 FUNC_ADD                = 0x8006;
+  const PRUint32 BLEND_EQUATION          = 0x8009;
+  const PRUint32 BLEND_EQUATION_RGB      = 0x8009;
+  const PRUint32 BLEND_EQUATION_ALPHA    = 0x883D;
+  const PRUint32 FUNC_SUBTRACT           = 0x800A;
+  const PRUint32 FUNC_REVERSE_SUBTRACT   = 0x800B;
+  const PRUint32 BLEND_DST_RGB           = 0x80C8;
+  const PRUint32 BLEND_SRC_RGB           = 0x80C9;
+  const PRUint32 BLEND_DST_ALPHA         = 0x80CA;
+  const PRUint32 BLEND_SRC_ALPHA         = 0x80CB;
+  const PRUint32 CONSTANT_COLOR          = 0x8001;
+  const PRUint32 ONE_MINUS_CONSTANT_COLOR = 0x8002;
+  const PRUint32 CONSTANT_ALPHA          = 0x8003;
+  const PRUint32 ONE_MINUS_CONSTANT_ALPHA = 0x8004;
+  const PRUint32 BLEND_COLOR             = 0x8005;
+  const PRUint32 ARRAY_BUFFER            = 0x8892;
+  const PRUint32 ELEMENT_ARRAY_BUFFER    = 0x8893;
+  const PRUint32 ARRAY_BUFFER_BINDING    = 0x8894;
+  const PRUint32 ELEMENT_ARRAY_BUFFER_BINDING = 0x8895;
+  const PRUint32 STREAM_DRAW             = 0x88E0;
+  const PRUint32 STATIC_DRAW             = 0x88E4;
+  const PRUint32 DYNAMIC_DRAW            = 0x88E8;
+  const PRUint32 BUFFER_SIZE             = 0x8764;
+  const PRUint32 BUFFER_USAGE            = 0x8765;
+  const PRUint32 CURRENT_VERTEX_ATTRIB   = 0x8626;
+  const PRUint32 FRONT                   = 0x0404;
+  const PRUint32 BACK                    = 0x0405;
+  const PRUint32 FRONT_AND_BACK          = 0x0408;
+  const PRUint32 TEXTURE_2D              = 0x0DE1;
+  const PRUint32 CULL_FACE               = 0x0B44;
+  const PRUint32 BLEND                   = 0x0BE2;
+  const PRUint32 DITHER                  = 0x0BD0;
+  const PRUint32 STENCIL_TEST            = 0x0B90;
+  const PRUint32 DEPTH_TEST              = 0x0B71;
+  const PRUint32 SCISSOR_TEST            = 0x0C11;
+  const PRUint32 POLYGON_OFFSET_FILL     = 0x8037;
+  const PRUint32 SAMPLE_ALPHA_TO_COVERAGE = 0x809E;
+  const PRUint32 SAMPLE_COVERAGE         = 0x80A0;
+  const PRUint32 NO_ERROR                = 0;
+  const PRUint32 INVALID_ENUM            = 0x0500;
+  const PRUint32 INVALID_VALUE           = 0x0501;
+  const PRUint32 INVALID_OPERATION       = 0x0502;
+  const PRUint32 OUT_OF_MEMORY           = 0x0505;
+  const PRUint32 CW                      = 0x0900;
+  const PRUint32 CCW                     = 0x0901;
+  const PRUint32 LINE_WIDTH              = 0x0B21;
+  const PRUint32 ALIASED_POINT_SIZE_RANGE = 0x846D;
+  const PRUint32 ALIASED_LINE_WIDTH_RANGE = 0x846E;
+  const PRUint32 CULL_FACE_MODE          = 0x0B45;
+  const PRUint32 FRONT_FACE              = 0x0B46;
+  const PRUint32 DEPTH_RANGE             = 0x0B70;
+  const PRUint32 DEPTH_WRITEMASK         = 0x0B72;
+  const PRUint32 DEPTH_CLEAR_VALUE       = 0x0B73;
+  const PRUint32 DEPTH_FUNC              = 0x0B74;
+  const PRUint32 STENCIL_CLEAR_VALUE     = 0x0B91;
+  const PRUint32 STENCIL_FUNC            = 0x0B92;
+  const PRUint32 STENCIL_FAIL            = 0x0B94;
+  const PRUint32 STENCIL_PASS_DEPTH_FAIL = 0x0B95;
+  const PRUint32 STENCIL_PASS_DEPTH_PASS = 0x0B96;
+  const PRUint32 STENCIL_REF             = 0x0B97;
+  const PRUint32 STENCIL_VALUE_MASK      = 0x0B93;
+  const PRUint32 STENCIL_WRITEMASK       = 0x0B98;
+  const PRUint32 STENCIL_BACK_FUNC       = 0x8800;
+  const PRUint32 STENCIL_BACK_FAIL       = 0x8801;
+  const PRUint32 STENCIL_BACK_PASS_DEPTH_FAIL = 0x8802;
+  const PRUint32 STENCIL_BACK_PASS_DEPTH_PASS = 0x8803;
+  const PRUint32 STENCIL_BACK_REF        = 0x8CA3;
+  const PRUint32 STENCIL_BACK_VALUE_MASK = 0x8CA4;
+  const PRUint32 STENCIL_BACK_WRITEMASK  = 0x8CA5;
+  const PRUint32 VIEWPORT                = 0x0BA2;
+  const PRUint32 SCISSOR_BOX             = 0x0C10;
+  const PRUint32 COLOR_CLEAR_VALUE       = 0x0C22;
+  const PRUint32 COLOR_WRITEMASK         = 0x0C23;
+  const PRUint32 UNPACK_ALIGNMENT        = 0x0CF5;
+  const PRUint32 PACK_ALIGNMENT          = 0x0D05;
+  const PRUint32 MAX_TEXTURE_SIZE        = 0x0D33;
+  const PRUint32 MAX_VIEWPORT_DIMS       = 0x0D3A;
+  const PRUint32 SUBPIXEL_BITS           = 0x0D50;
+  const PRUint32 RED_BITS                = 0x0D52;
+  const PRUint32 GREEN_BITS              = 0x0D53;
+  const PRUint32 BLUE_BITS               = 0x0D54;
+  const PRUint32 ALPHA_BITS              = 0x0D55;
+  const PRUint32 DEPTH_BITS              = 0x0D56;
+  const PRUint32 STENCIL_BITS            = 0x0D57;
+  const PRUint32 POLYGON_OFFSET_UNITS    = 0x2A00;
+  const PRUint32 POLYGON_OFFSET_FACTOR   = 0x8038;
+  const PRUint32 TEXTURE_BINDING_2D      = 0x8069;
+  const PRUint32 SAMPLE_BUFFERS          = 0x80A8;
+  const PRUint32 SAMPLES                 = 0x80A9;
+  const PRUint32 SAMPLE_COVERAGE_VALUE   = 0x80AA;
+  const PRUint32 SAMPLE_COVERAGE_INVERT  = 0x80AB;
+  const PRUint32 NUM_COMPRESSED_TEXTURE_FORMATS = 0x86A2;
+  const PRUint32 COMPRESSED_TEXTURE_FORMATS = 0x86A3;
+  const PRUint32 DONT_CARE               = 0x1100;
+  const PRUint32 FASTEST                 = 0x1101;
+  const PRUint32 NICEST                  = 0x1102;
+  const PRUint32 GENERATE_MIPMAP_HINT    = 0x8192;
+  const PRUint32 BYTE                    = 0x1400;
+  const PRUint32 UNSIGNED_BYTE           = 0x1401;
+  const PRUint32 SHORT                   = 0x1402;
+  const PRUint32 UNSIGNED_SHORT          = 0x1403;
+  const PRUint32 INT                     = 0x1404;
+  const PRUint32 UNSIGNED_INT            = 0x1405;
+  const PRUint32 FLOAT                   = 0x1406;
+  const PRUint32 FIXED                   = 0x140C;
+  const PRUint32 DEPTH_COMPONENT         = 0x1902;
+  const PRUint32 ALPHA                   = 0x1906;
+  const PRUint32 RGB                     = 0x1907;
+  const PRUint32 RGBA                    = 0x1908;
+  const PRUint32 LUMINANCE               = 0x1909;
+  const PRUint32 LUMINANCE_ALPHA         = 0x190A;
+  const PRUint32 UNSIGNED_SHORT_4_4_4_4  = 0x8033;
+  const PRUint32 UNSIGNED_SHORT_5_5_5_1  = 0x8034;
+  const PRUint32 UNSIGNED_SHORT_5_6_5    = 0x8363;
+  const PRUint32 FRAGMENT_SHADER         = 0x8B30;
+  const PRUint32 VERTEX_SHADER           = 0x8B31;
+  const PRUint32 MAX_VERTEX_ATTRIBS      = 0x8869;
+  const PRUint32 MAX_VERTEX_UNIFORM_VECTORS = 0x8DFB;
+  const PRUint32 MAX_VARYING_VECTORS     = 0x8DFC;
+  const PRUint32 MAX_COMBINED_TEXTURE_IMAGE_UNITS = 0x8B4D;
+  const PRUint32 MAX_VERTEX_TEXTURE_IMAGE_UNITS = 0x8B4C;
+  const PRUint32 MAX_TEXTURE_IMAGE_UNITS = 0x8872;
+  const PRUint32 MAX_FRAGMENT_UNIFORM_VECTORS = 0x8DFD;
+  const PRUint32 SHADER_TYPE             = 0x8B4F;
+  const PRUint32 DELETE_STATUS           = 0x8B80;
+  const PRUint32 LINK_STATUS             = 0x8B82;
+  const PRUint32 VALIDATE_STATUS         = 0x8B83;
+  const PRUint32 ATTACHED_SHADERS        = 0x8B85;
+  const PRUint32 ACTIVE_UNIFORMS         = 0x8B86;
+  const PRUint32 ACTIVE_UNIFORM_MAX_LENGTH = 0x8B87;
+  const PRUint32 ACTIVE_ATTRIBUTES       = 0x8B89;
+  const PRUint32 ACTIVE_ATTRIBUTE_MAX_LENGTH = 0x8B8A;
+  const PRUint32 SHADING_LANGUAGE_VERSION = 0x8B8C;
+  const PRUint32 CURRENT_PROGRAM         = 0x8B8D;
+  const PRUint32 NEVER                   = 0x0200;
+  const PRUint32 LESS                    = 0x0201;
+  const PRUint32 EQUAL                   = 0x0202;
+  const PRUint32 LEQUAL                  = 0x0203;
+  const PRUint32 GREATER                 = 0x0204;
+  const PRUint32 NOTEQUAL                = 0x0205;
+  const PRUint32 GEQUAL                  = 0x0206;
+  const PRUint32 ALWAYS                  = 0x0207;
+  const PRUint32 KEEP                    = 0x1E00;
+  const PRUint32 REPLACE                 = 0x1E01;
+  const PRUint32 INCR                    = 0x1E02;
+  const PRUint32 DECR                    = 0x1E03;
+  const PRUint32 INVERT                  = 0x150A;
+  const PRUint32 INCR_WRAP               = 0x8507;
+  const PRUint32 DECR_WRAP               = 0x8508;
+  const PRUint32 VENDOR                  = 0x1F00;
+  const PRUint32 RENDERER                = 0x1F01;
+  const PRUint32 VERSION                 = 0x1F02;
+  const PRUint32 EXTENSIONS              = 0x1F03;
+  const PRUint32 NEAREST                 = 0x2600;
+  const PRUint32 LINEAR                  = 0x2601;
+  const PRUint32 NEAREST_MIPMAP_NEAREST  = 0x2700;
+  const PRUint32 LINEAR_MIPMAP_NEAREST   = 0x2701;
+  const PRUint32 NEAREST_MIPMAP_LINEAR   = 0x2702;
+  const PRUint32 LINEAR_MIPMAP_LINEAR    = 0x2703;
+  const PRUint32 TEXTURE_MAG_FILTER      = 0x2800;
+  const PRUint32 TEXTURE_MIN_FILTER      = 0x2801;
+  const PRUint32 TEXTURE_WRAP_S          = 0x2802;
+  const PRUint32 TEXTURE_WRAP_T          = 0x2803;
+  const PRUint32 TEXTURE                 = 0x1702;
+  const PRUint32 TEXTURE_CUBE_MAP        = 0x8513;
+  const PRUint32 TEXTURE_BINDING_CUBE_MAP = 0x8514;
+  const PRUint32 TEXTURE_CUBE_MAP_POSITIVE_X = 0x8515;
+  const PRUint32 TEXTURE_CUBE_MAP_NEGATIVE_X = 0x8516;
+  const PRUint32 TEXTURE_CUBE_MAP_POSITIVE_Y = 0x8517;
+  const PRUint32 TEXTURE_CUBE_MAP_NEGATIVE_Y = 0x8518;
+  const PRUint32 TEXTURE_CUBE_MAP_POSITIVE_Z = 0x8519;
+  const PRUint32 TEXTURE_CUBE_MAP_NEGATIVE_Z = 0x851A;
+  const PRUint32 MAX_CUBE_MAP_TEXTURE_SIZE = 0x851C;
+  const PRUint32 TEXTURE0                = 0x84C0;
+  const PRUint32 TEXTURE1                = 0x84C1;
+  const PRUint32 TEXTURE2                = 0x84C2;
+  const PRUint32 TEXTURE3                = 0x84C3;
+  const PRUint32 TEXTURE4                = 0x84C4;
+  const PRUint32 TEXTURE5                = 0x84C5;
+  const PRUint32 TEXTURE6                = 0x84C6;
+  const PRUint32 TEXTURE7                = 0x84C7;
+  const PRUint32 TEXTURE8                = 0x84C8;
+  const PRUint32 TEXTURE9                = 0x84C9;
+  const PRUint32 TEXTURE10               = 0x84CA;
+  const PRUint32 TEXTURE11               = 0x84CB;
+  const PRUint32 TEXTURE12               = 0x84CC;
+  const PRUint32 TEXTURE13               = 0x84CD;
+  const PRUint32 TEXTURE14               = 0x84CE;
+  const PRUint32 TEXTURE15               = 0x84CF;
+  const PRUint32 TEXTURE16               = 0x84D0;
+  const PRUint32 TEXTURE17               = 0x84D1;
+  const PRUint32 TEXTURE18               = 0x84D2;
+  const PRUint32 TEXTURE19               = 0x84D3;
+  const PRUint32 TEXTURE20               = 0x84D4;
+  const PRUint32 TEXTURE21               = 0x84D5;
+  const PRUint32 TEXTURE22               = 0x84D6;
+  const PRUint32 TEXTURE23               = 0x84D7;
+  const PRUint32 TEXTURE24               = 0x84D8;
+  const PRUint32 TEXTURE25               = 0x84D9;
+  const PRUint32 TEXTURE26               = 0x84DA;
+  const PRUint32 TEXTURE27               = 0x84DB;
+  const PRUint32 TEXTURE28               = 0x84DC;
+  const PRUint32 TEXTURE29               = 0x84DD;
+  const PRUint32 TEXTURE30               = 0x84DE;
+  const PRUint32 TEXTURE31               = 0x84DF;
+  const PRUint32 ACTIVE_TEXTURE          = 0x84E0;
+  const PRUint32 REPEAT                  = 0x2901;
+  const PRUint32 CLAMP_TO_EDGE           = 0x812F;
+  const PRUint32 MIRRORED_REPEAT         = 0x8370;
+  const PRUint32 FLOAT_VEC2              = 0x8B50;
+  const PRUint32 FLOAT_VEC3              = 0x8B51;
+  const PRUint32 FLOAT_VEC4              = 0x8B52;
+  const PRUint32 INT_VEC2                = 0x8B53;
+  const PRUint32 INT_VEC3                = 0x8B54;
+  const PRUint32 INT_VEC4                = 0x8B55;
+  const PRUint32 BOOL                    = 0x8B56;
+  const PRUint32 BOOL_VEC2               = 0x8B57;
+  const PRUint32 BOOL_VEC3               = 0x8B58;
+  const PRUint32 BOOL_VEC4               = 0x8B59;
+  const PRUint32 FLOAT_MAT2              = 0x8B5A;
+  const PRUint32 FLOAT_MAT3              = 0x8B5B;
+  const PRUint32 FLOAT_MAT4              = 0x8B5C;
+  const PRUint32 SAMPLER_2D              = 0x8B5E;
+  const PRUint32 SAMPLER_CUBE            = 0x8B60;
+  const PRUint32 VERTEX_ATTRIB_ARRAY_ENABLED = 0x8622;
+  const PRUint32 VERTEX_ATTRIB_ARRAY_SIZE = 0x8623;
+  const PRUint32 VERTEX_ATTRIB_ARRAY_STRIDE = 0x8624;
+  const PRUint32 VERTEX_ATTRIB_ARRAY_TYPE = 0x8625;
+  const PRUint32 VERTEX_ATTRIB_ARRAY_NORMALIZED = 0x886A;
+  const PRUint32 VERTEX_ATTRIB_ARRAY_POINTER = 0x8645;
+  const PRUint32 VERTEX_ATTRIB_ARRAY_BUFFER_BINDING = 0x889F;
+  const PRUint32 IMPLEMENTATION_COLOR_READ_TYPE = 0x8B9A;
+  const PRUint32 IMPLEMENTATION_COLOR_READ_FORMAT = 0x8B9B;
+  const PRUint32 COMPILE_STATUS          = 0x8B81;
+  const PRUint32 INFO_LOG_LENGTH         = 0x8B84;
+  const PRUint32 SHADER_SOURCE_LENGTH    = 0x8B88;
+  const PRUint32 SHADER_COMPILER         = 0x8DFA;
+  const PRUint32 SHADER_BINARY_FORMATS   = 0x8DF8;
+  const PRUint32 NUM_SHADER_BINARY_FORMATS = 0x8DF9;
+  const PRUint32 LOW_FLOAT               = 0x8DF0;
+  const PRUint32 MEDIUM_FLOAT            = 0x8DF1;
+  const PRUint32 HIGH_FLOAT              = 0x8DF2;
+  const PRUint32 LOW_INT                 = 0x8DF3;
+  const PRUint32 MEDIUM_INT              = 0x8DF4;
+  const PRUint32 HIGH_INT                = 0x8DF5;
+  const PRUint32 FRAMEBUFFER             = 0x8D40;
+  const PRUint32 RENDERBUFFER            = 0x8D41;
+  const PRUint32 RGBA4                   = 0x8056;
+  const PRUint32 RGB5_A1                 = 0x8057;
+  const PRUint32 RGB565                  = 0x8D62;
+  const PRUint32 DEPTH_COMPONENT16       = 0x81A5;
+  const PRUint32 STENCIL_INDEX           = 0x1901;
+  const PRUint32 STENCIL_INDEX8          = 0x8D48;
+  const PRUint32 RENDERBUFFER_WIDTH      = 0x8D42;
+  const PRUint32 RENDERBUFFER_HEIGHT     = 0x8D43;
+  const PRUint32 RENDERBUFFER_INTERNAL_FORMAT = 0x8D44;
+  const PRUint32 RENDERBUFFER_RED_SIZE   = 0x8D50;
+  const PRUint32 RENDERBUFFER_GREEN_SIZE = 0x8D51;
+  const PRUint32 RENDERBUFFER_BLUE_SIZE  = 0x8D52;
+  const PRUint32 RENDERBUFFER_ALPHA_SIZE = 0x8D53;
+  const PRUint32 RENDERBUFFER_DEPTH_SIZE = 0x8D54;
+  const PRUint32 RENDERBUFFER_STENCIL_SIZE = 0x8D55;
+  const PRUint32 FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE = 0x8CD0;
+  const PRUint32 FRAMEBUFFER_ATTACHMENT_OBJECT_NAME = 0x8CD1;
+  const PRUint32 FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL = 0x8CD2;
+  const PRUint32 FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE = 0x8CD3;
+  const PRUint32 COLOR_ATTACHMENT0       = 0x8CE0;
+  const PRUint32 DEPTH_ATTACHMENT        = 0x8D00;
+  const PRUint32 STENCIL_ATTACHMENT      = 0x8D20;
+  const PRUint32 NONE                    = 0;
+  const PRUint32 FRAMEBUFFER_COMPLETE    = 0x8CD5;
+  const PRUint32 FRAMEBUFFER_INCOMPLETE_ATTACHMENT = 0x8CD6;
+  const PRUint32 FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT = 0x8CD7;
+  const PRUint32 FRAMEBUFFER_INCOMPLETE_DIMENSIONS = 0x8CD9;
+  const PRUint32 FRAMEBUFFER_UNSUPPORTED = 0x8CDD;
+  const PRUint32 FRAMEBUFFER_BINDING     = 0x8CA6;
+  const PRUint32 RENDERBUFFER_BINDING    = 0x8CA7;
+  const PRUint32 MAX_RENDERBUFFER_SIZE   = 0x84E8;
+  const PRUint32 INVALID_FRAMEBUFFER_OPERATION = 0x0506;
+  const PRUint32 MULTISAMPLE             = 0x809D;
+
+  // Other
+  void swapBuffers ();
+
+};
new file mode 100644
--- /dev/null
+++ b/dom/interfaces/canvas/nsICanvasRenderingContextGLBuffer.idl
@@ -0,0 +1,91 @@
+/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is canvas 3D.
+ *
+ * The Initial Developer of the Original Code is
+ *   Mozilla Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 2007
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   Vladimir Vukicevic <vladimir@pobox.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include "nsISupports.idl"
+
+interface nsICanvasRenderingContextGL;
+
+[scriptable, uuid(14eb51cd-febe-41fa-b833-4c599719121e)]
+interface nsICanvasRenderingContextGLBuffer : nsISupports
+{
+  readonly attribute nsICanvasRenderingContextGL ownerContext;
+  readonly attribute PRBool disposed;
+
+  // immediately free the memory held by this buffer,
+  // even before this object is destroyed (e.g. by the JS GC)
+  void dispose();
+
+  readonly attribute PRUint32 usage;  // either STATIC_DRAW or DYNAMIC_DRAW
+  readonly attribute PRUint32 length; // number of elements
+  readonly attribute PRUint32 type;   // type of each element
+};
+
+[scriptable, uuid(27a45ca4-0847-4f2e-8e32-6d4966ff3e56)]
+interface nsICanvasRenderingContextGLTexture : nsISupports
+{
+  readonly attribute nsICanvasRenderingContextGL ownerContext;
+  readonly attribute PRBool disposed;
+
+  const PRUint32 TARGET_2D = 0;
+  const PRUint32 TARGET_RECT = 1;
+
+  readonly attribute PRUint32 target;
+
+  // in pixels; the texture coordinates
+  // are 0..w/h for TARGET_RECT, or 0.0 .. 1.0
+  // for TARGET_2D
+  readonly attribute PRUint32 width;
+  readonly attribute PRUint32 height;
+
+  const PRUint32 FILTER_TYPE_MAG = 0;
+  const PRUint32 FILTER_TYPE_MIN = 1;
+  const PRUint32 FILTER_NEAREST = 0;
+  const PRUint32 FILTER_LINER = 1;
+
+  void setFilter (in PRUint32 filterType, in PRUint32 filterMode);
+
+  const PRUint32 WRAP_TYPE_S = 0;
+  const PRUint32 WRAP_TYPE_T = 0;
+
+  const PRUint32 WRAP_CLAMP_TO_EDGE = 1;
+  const PRUint32 WRAP_REPEAT = 3;
+  const PRUint32 WRAP_MIRRORED_REPEAT = 4;
+
+  void setWrap (in PRUint32 wrapType, in PRUint32 wrapMode);
+};
+
new file mode 100644
--- /dev/null
+++ b/dom/interfaces/canvas/nsICanvasRenderingContextGLWeb20.idl
@@ -0,0 +1,249 @@
+/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is canvas 3D.
+ *
+ * The Initial Developer of the Original Code is
+ *   Mozilla Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 2006
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   Vladimir Vukicevic <vladimir@pobox.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include "nsICanvasRenderingContextGL.idl"
+#include "nsICanvasRenderingContextGLBuffer.idl"
+
+interface nsIDOMHTMLElement;
+
+[scriptable, uuid(209a9c93-495e-4085-a3e4-29354b404cc4)]
+interface nsICanvasRenderingContextGLWeb20 : nsICanvasRenderingContextGL
+{
+  void activeTexture (in PRUint32 texture);
+
+  void attachShader (in PRUint32 program, in PRUint32 shader);
+  void bindAttribLocation (in PRUint32 program, in PRUint32 index, in string name);
+
+  void bindBuffer (in PRUint32 target, in PRUint32 buffer);
+  void bindTexture (in PRUint32 target, in PRUint32 texid);
+
+  void blendColor (in float red, in float green, in float blue, in float alpha);
+  void blendEquation (in PRUint32 mode);
+  void blendEquationSeparate (in PRUint32 modeRGB, in PRUint32 modeAlpha);
+  void blendFunc (in PRUint32 sfactor, in PRUint32 dfactor);
+  void blendFuncSeparate (in PRUint32 srcRGB, in PRUint32 dstRGB, in PRUint32 srcAlpha, in PRUint32 dstAlpha);
+
+  
+  void bufferData (/*in PRUint32 target, in object[] array, in PRUint32 type, in PRUint32 usage*/);
+  void bufferSubData (/*in PRUint32 target, in PRUint32 offset, in object[] array, in PRUint32 type*/);
+
+  void clear (in PRUint32 mask);
+  void clearColor (in float red, in float green, in float blue, in float alpha);
+  void clearDepth (in float depth);
+  void clearStencil (in PRInt32 s);
+  void colorMask (in boolean red, in boolean green, in boolean blue, in boolean alpha);
+  // NO compressedTexImage2D
+  // NO compressedTexSubImage2D
+
+  void copyTexImage2D (in PRUint32 target, in PRInt32 level, in PRUint32 internalFormat, in PRInt32 x, in PRInt32 y, in PRUint32 width, in PRUint32 height, in PRInt32 border);
+  void copyTexSubImage2D (in PRUint32 target, in PRInt32 level, in PRInt32 xoffset, in PRInt32 yoffset, in PRInt32 x, in PRInt32 y, in PRUint32 width, in PRUint32 height);
+
+  PRUint32 createProgram ();
+  PRUint32 createShader (in PRUint32 type);
+  void cullFace (in PRUint32 face);
+
+  void deleteBuffers (/*in PRUint32[] buffers*/);
+  void deleteTextures (/*in PRUint32[] textures*/);
+  void deleteProgram (in PRUint32 program);
+  void deleteShader (in PRUint32 shader);
+  void detachShader (in PRUint32 program, in PRUint32 shader);
+  void depthFunc (in PRUint32 func);
+  void depthMask (in boolean flag);
+  void depthRange (in float zNear, in float zFar);
+  void disable (in PRUint32 mode);
+  void disableVertexAttribArray (in PRUint32 index);
+  void drawArrays (in PRUint32 mode, in PRUint32 first, in PRUint32 count);
+  void drawElements (/*in PRUint32 mode, in PRUint32 count, in PRUint32 type, in PRUint32[] indices*/);
+  void enable (in PRUint32 mode);
+  void enableVertexAttribArray (in PRUint32 index);
+  void finish();
+  void flush();
+  void frontFace (in PRUint32 face);
+
+  // getActiveAttrib returns an object: { name: "..", size: .., type: .. }
+  void getActiveAttrib (in PRUint32 program, in PRUint32 index);
+
+  // getActiveUniform returns an object: { name: "..", size: .., type: .. }
+  void getActiveUniform (in PRUint32 program, in PRUint32 index);
+
+  // returns an array of shader IDs
+  void getAttachedShaders (in PRUint32 program);
+
+  PRInt32 getAttribLocation (in PRUint32 program, in string name);
+
+  // getBooleanv, getIntegerv, getFloatv, getDoublev, getString
+  // are all rolled into a single function that uses scriptable
+  // magic to return the right type of jsobj.  Colors are always
+  // returned as normalized floats (0.0 .. 1.0).
+
+  void getParameter (in PRUint32 pname);
+  void getBufferParameter (in PRUint32 target, in PRUint32 pname);
+
+  void genBuffers (in PRUint32 n);
+  void genTextures (in PRUint32 n);
+
+  void generateMipmap (in PRUint32 target);
+
+  PRUint32 getError ();
+
+  void getProgramParameter (in PRUint32 program, in PRUint32 pname);
+
+  string getProgramInfoLog (in PRUint32 program);
+
+  void getTexParameter(in PRUint32 target, in PRUint32 pname);
+
+  void getUniform (in PRUint32 program, in PRUint32 location);
+  PRInt32 getUniformLocation (in PRUint32 program, in string name);
+
+  void getVertexAttrib (in PRUint32 index, in PRUint32 pname);
+  // NO void getVertexAttribPointerv 
+
+  void hint (in PRUint32 target, in PRUint32 mode);
+
+  boolean isBuffer (in PRUint32 buffer);
+  boolean isEnabled (in PRUint32 cap);
+  boolean isProgram (in PRUint32 program);
+  boolean isShader (in PRUint32 shader);
+  boolean isTexture (in PRUint32 texture);
+
+  void lineWidth (in float width);
+  void linkProgram (in PRUint32 program);
+
+  // NO pixelStore
+
+  void pixelStore (in PRUint32 pname, in PRInt32 param);
+
+  void polygonOffset (in float factor, in float units);
+
+  void readPixels (in PRUint32 x, in PRUint32 y, in PRUint32 width, in PRUint32 height, in PRUint32 format, in PRUint32 type);
+
+  void sampleCoverage (in float value, in boolean invert);
+  void scissor (in PRInt32 x, in PRInt32 y, in PRInt32 width, in PRInt32 height);
+  void stencilFunc (in PRUint32 func, in PRInt32 ref, in PRUint32 mask);
+  void stencilFuncSeparate (in PRUint32 face, in PRUint32 func, in PRInt32 ref, in PRUint32 mask);
+  void stencilMask (in PRUint32 mask);
+  void stencilMaskSeparate (in PRUint32 face, in PRUint32 mask);
+  void stencilOp (in PRUint32 fail, in PRUint32 zfail, in PRUint32 zpass);
+  void stencilOpSeparate (in PRUint32 face, in PRUint32 fail, in PRUint32 zfail, in PRUint32 zpass);
+
+  void texSubImage2D ();
+  void texImage2D ();
+  void texSubImage2DHTML (in PRUint32 target, in PRUint32 level, in PRInt32 x, in PRInt32 y, in nsIDOMHTMLElement imageOrCanvas);
+  void texImage2DHTML (in PRUint32 target, in PRUint32 level, in nsIDOMHTMLElement imageOrCanvas);
+
+  void texParameter();
+
+  // YES void texSubImage2DHTML (...);
+
+  void uniform1i(in PRUint32 id, in PRInt32 x);
+  void uniform2i(in PRUint32 id, in PRInt32 x, in PRInt32 y);
+  void uniform3i(in PRUint32 id, in PRInt32 x, in PRInt32 y, in PRInt32 z);
+  void uniform4i(in PRUint32 id, in PRInt32 x, in PRInt32 y, in PRInt32 z, in PRInt32 w);
+ 
+  void uniform1iv(/*in PRUint32 id, in int[] array */);
+  void uniform2iv(/*in PRUint32 id, in int[] array */);
+  void uniform3iv(/*in PRUint32 id, in int[] array */);
+  void uniform4iv(/*in PRUint32 id, in int[] array */);
+
+  void uniform1f(in PRUint32 id, in float x);
+  void uniform2f(in PRUint32 id, in float x, in float y);
+  void uniform3f(in PRUint32 id, in float x, in float y, in float z);
+  void uniform4f(in PRUint32 id, in float x, in float y, in float z, in float w);
+  
+  void uniform1fv(/*in PRUint32 id, in float[] array */);
+  void uniform2fv(/*in PRUint32 id, in float[] array */);
+  void uniform3fv(/*in PRUint32 id, in float[] array */);
+  void uniform4fv(/*in PRUint32 id, in float[] array */);
+
+  void uniformMatrix2fv(/*in PRUint32 id, in float[] array */);
+  void uniformMatrix3fv(/*in PRUint32 id, in float[] array */);
+  void uniformMatrix4fv(/*in PRUint32 id, in float[] array */);
+
+  void useProgram (in PRUint32 program);
+  void validateProgram (in PRUint32 program);
+
+  void vertexAttrib1f(in PRUint32 id, in float x);
+  void vertexAttrib2f(in PRUint32 id, in float x, in float y);
+  void vertexAttrib3f(in PRUint32 id, in float x, in float y, in float z);
+  void vertexAttrib4f(in PRUint32 id, in float x, in float y, in float z, in float w);
+
+  void vertexAttrib1fv(/*in PRUint32 id, in float[] array*/);
+  void vertexAttrib2fv(/*in PRUint32 id, in float[] array*/);
+  void vertexAttrib3fv(/*in PRUint32 id, in float[] array*/);
+  void vertexAttrib4fv(/*in PRUint32 id, in float[] array*/);
+
+  void vertexAttribPointer (/*in PRUint32 index, in PRInt32 size, in PRUint32 type, in PRBool normalized, in PRUint32 stride, in Object[] array*/);
+
+  void viewport (in PRInt32 x, in PRInt32 y, in PRInt32 width, in PRInt32 height);
+
+  void compileShader (in PRUint32 shader);
+  void getShaderParameter (in PRUint32 shader, in PRUint32 pname);
+  string getShaderInfoLog (in PRUint32 shader);
+  string getShaderSource (in PRUint32 shader);
+  void shaderSource(in PRUint32 shader, in string source);
+
+  void getImageData (in PRUint32 x, in PRUint32 y, in PRUint32 width, in PRUint32 height);
+
+  //
+  // framebuffer_object methods
+  //
+
+  void bindRenderbuffer (in PRUint32 target, in PRUint32 renderbuffer);
+  boolean isRenderbuffer (in PRUint32 renderbuffer);
+  void deleteRenderbuffers (/*in PRUint32[] renderbuffers*/);
+  void genRenderbuffers (in PRUint32 n);
+
+  void renderbufferStorage (in PRUint32 target, in PRUint32 internalFormat, in PRUint32 width, in PRUint32 height);
+
+  void getRenderbufferParameter (in PRUint32 target, in PRUint32 pname);
+
+  void bindFramebuffer (in PRUint32 target, in PRUint32 framebuffer);
+  boolean isFramebuffer (in PRUint32 framebuffer);
+  void deleteFramebuffers (/*in PRUint32[] framebuffers*/);
+  void genFramebuffers (in PRUint32 n);
+
+  PRUint32 checkFramebufferStatus (in PRUint32 target);
+
+  void framebufferTexture2D (in PRUint32 target, in PRUint32 attachmentPoint, in PRUint32 textureTarget, in PRUint32 texture, in PRInt32 level);
+
+  void framebufferRenderbuffer (in PRUint32 target, in PRUint32 attachmentPoint, in PRUint32 renderbufferTarget, in PRUint32 renderbuffer);
+
+  void getFramebufferAttachmentParameter (in PRUint32 target, in PRUint32 attachment, in PRUint32 pname);
+
+};
+