checkpointing this work (npotb)
authorvladimir@pobox.com
Wed, 04 Apr 2007 20:47:20 -0700
changeset 356 a283dc02a6ab3470aec6a8759f70c6dc192d5da7
parent 355 48edc39ac3ec8a5d727e2ddfb7b55c2d47a8d0af
child 357 4548f59ad634d60a143407afdaf2b64e41c47a74
push id1
push userbsmedberg@mozilla.com
push dateThu, 20 Mar 2008 16:49:24 +0000
treeherdermozilla-central@61007906a1f8 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
milestone1.9a4pre
checkpointing this work (npotb)
extensions/canvas3d/doc/glweb20spec.html
extensions/canvas3d/install.rdf
extensions/canvas3d/public/Makefile.in
extensions/canvas3d/public/nsICanvasGLPrivate.idl
extensions/canvas3d/public/nsICanvasRenderingContextGL.idl
extensions/canvas3d/public/nsICanvasRenderingContextGLES11.idl
extensions/canvas3d/public/nsICanvasRenderingContextGLWeb20.idl
extensions/canvas3d/src/Makefile.in
extensions/canvas3d/src/nsCanvas3DModule.cpp
extensions/canvas3d/src/nsCanvasRenderingContextGL.cpp
extensions/canvas3d/src/nsCanvasRenderingContextGL.h
extensions/canvas3d/src/nsCanvasRenderingContextGLES11.cpp
extensions/canvas3d/src/nsCanvasRenderingContextGLWeb20.cpp
new file mode 100644
--- /dev/null
+++ b/extensions/canvas3d/doc/glweb20spec.html
@@ -0,0 +1,640 @@
+
+<html>
+<head>
+    <style type="text/css">
+
+.glfuncs {
+      border: 1px solid gray;
+      width: 100%;
+      font-family: Lucida Sans Console, Lucida Console, Bitstream Vera Mono, Courier New, Courier, monospace;
+      font-size: x-small;
+}
+
+.gldifferent {
+      background: #ffeeee;
+}
+
+tr > th {
+      font-family: sans;
+      font-size: small;
+      background: #dddddd;
+}
+
+.glgroup {
+      padding-top: 5px;
+      font-family: sans;
+      font-size: small;
+      background: #ddddff;
+}
+
+    </style>
+</head>
+
+<body>
+
+<h3>API Mapping</h3>
+<table class="glfuncs">
+<tr style="font-family: sans">
+<th width="50%">GL ES 2.0</th>
+<th>GLWeb20Context</th>
+</tr>
+
+<tr><td class="glgroup" colspan="2"><b><i>Core GL ES 2.0</i></b></td></tr>
+
+<tr>
+<td>ActiveTexture (GLenum texture)</td>
+</tr>
+
+<tr>
+<td>AttachShader (GLuint program, GLuint shader)</td>
+</tr>
+
+<tr>
+<td>BindAttribLocation (GLuint program, GLuint index, const char *name)</td>
+</tr>
+
+<tr>
+<td>BindBuffer (GLenum target, GLuint buffer)</td>
+</tr>
+
+<tr>
+<td>BindTexture (GLenum target, GLuint texture)</td>
+</tr>
+
+<tr>
+<td>BlendColor (GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)</td>
+</tr>
+
+<tr>
+<td>BlendEquation (GLenum mode)</td>
+</tr>
+
+<tr>
+<td>BlendEquationSeparate (GLenum modeRGB, GLenum modeAlpha)</td>
+</tr>
+
+<tr>
+<td>BlendFunc (GLenum sfactor, GLenum dfactor)</td>
+</tr>
+
+<tr>
+<td>BlendFuncSeparate (GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha)</td>
+</tr>
+
+<tr class="gldifferent">
+<td>BufferData (GLenum target, GLsizeiptr size, const void *data, GLenum usage)</td>
+<td>bufferData (uint target, Array data, uint elementType, uint usage)</td>
+</tr>
+
+<tr class="gldifferent">
+<td>BufferSubData (GLenum target, GLintptr offset, GLsizeiptr size, const void *data)</td>
+<td>bufferSubData (uint target, uint offset, Array data, uint elementType)</td>
+</tr>
+
+<tr>
+<td>Clear (GLbitfield mask)</td>
+</tr>
+
+<tr>
+<td>ClearColor (GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)</td>
+</tr>
+
+<tr class="gldifferent">
+<td>ClearDepthf (GLclampf depth)</td>
+<td>clearDepth (float depth);</td>
+</tr>
+
+<tr>
+<td>ClearStencil (GLint s)</td>
+</tr>
+
+<tr>
+<td>ColorMask (GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha)</td>
+</tr>
+
+<tr class="gldifferent">
+<td>CompressedTexImage2D (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const void *data)</td>
+<td><i>see texImage2DHTML</i></td>
+</tr>
+
+<tr class="gldifferent">
+<td>CompressedTexSubImage2D (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *data)</td>
+<td><i>see texSubImage2DHTML</i></td>
+</tr>
+
+<tr class="gldifferent">
+<td>CopyTexImage2D (GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border)</td>
+<td><i>TODO</i></td>
+</tr>
+
+<tr class="gldifferent">
+<td>CopyTexSubImage2D (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height)</td>
+<td><i>TODO</i></td>
+</tr>
+
+<tr>
+<td>uint glCreateProgram (void)</td>
+</tr>
+
+<tr>
+<td>uint glCreateShader (GLenum type)</td>
+</tr>
+
+<tr>
+<td>CullFace (GLenum mode)</td>
+</tr>
+
+<tr class="gldifferent">
+<td>DeleteBuffers (GLsizei n, const GLuint *buffers)</td>
+<td>deleteBuffers (Array buffers)</td>
+</tr>
+
+<tr class="gldifferent">
+<td>DeleteTextures (GLsizei n, const GLuint *textures)</td>
+<td>deleteTextures (Array textures)</td>
+</tr>
+
+<tr>
+<td>DeleteProgram (GLuint program)</td>
+</tr>
+
+<tr>
+<td>DeleteShader (GLuint shader)</td>
+</tr>
+
+<tr>
+<td>DetachShader (GLuint program, GLuint shader)</td>
+</tr>
+
+<tr>
+<td>DepthFunc (GLenum func)</td>
+<td></td>
+</tr>
+
+<tr>
+<td>DepthMask (GLboolean flag)</td>
+<td></td>
+</tr>
+
+<tr>
+<td>DepthRangef (GLclampf zNear, GLclampf zFar)</td>
+<td></td>
+</tr>
+
+<tr>
+<td>Disable (GLenum cap)</td>
+<td></td>
+</tr>
+
+<tr>
+<td>DisableVertexAttribArray (GLuint index)</td>
+<td></td>
+</tr>
+
+<tr>
+<td>DrawArrays (GLenum mode, GLint first, GLsizei count)</td>
+<td></td>
+</tr>
+
+<tr class="gldifferent">
+<td>DrawElements (GLenum mode, GLsizei count, GLenum type, const void *indices)</td>
+<td><i>TODO</i></td>
+</tr>
+
+<tr>
+<td>Enable (GLenum cap)</td>
+<td></td>
+</tr>
+
+<tr>
+<td>EnableVertexAttribArray (GLuint index)</td>
+<td></td>
+</tr>
+
+<tr class="gldifferent">
+<td>Finish (void)</td>
+<td><i>NONE</i></td>
+</tr>
+
+<tr class="gldifferent">
+<td>Flush (void)</td>
+<td><i>NONE</i></td>
+</tr>
+
+<tr>
+<td>FrontFace (GLenum mode)</td>
+<td></td>
+</tr>
+
+<tr class="gldifferent">
+<td>GetActiveAttrib (GLuint program, GLuint index, GLsizei bufsize, GLsizei *length, GLint *size, GLenum *type, char *name)</td><td>Object getActiveAttrib (uint program, uint index)<br>
+obj = { type: ..., size: ..., name: ... }</td>
+</tr>
+
+<tr class="gldifferent">
+<td>GetActiveUniform (GLuint program, GLuint index, GLsizei bufsize, GLsizei *length, GLint *size, GLenum *type, char *name)</td>
+<td>Object getActiveUniform (uint program, uint index)<br>
+obj = { type: ..., size: ..., name: ... }</td>
+</tr>
+
+<tr class="gldifferent">
+<td>GetAttachedShaders (GLuint program, GLsizei maxcount, GLsizei *count, GLuint *shaders)</td>
+<td>Array getAttachedShaders (uint program)</td>
+</tr>
+
+<tr class="gldifferent">
+<td>int glGetAttribLocation (GLuint program, const char *name)</td>
+<td>int getAttribLocation (uint program, string name)</td>
+</tr>
+
+<tr class="gldifferent">
+<td>GetBooleanv (GLenum pname, GLboolean *params)</td>
+<td><i>see getParameter</i></td>
+</tr>
+
+<tr class="gldifferent">
+<td>GetBufferParameteriv (GLenum target, GLenum pname, GLint *params)</td>
+<td><i>see getBufferParameter</i></td>
+</tr>
+
+<tr class="gldifferent">
+<td>GenBuffers (GLsizei n, GLuint *buffers)</td>
+<td>Array genBuffers (uint n)</td>
+</tr>
+
+<tr class="gldifferent">
+<td>GenTextures (GLsizei n, GLuint *textures)</td>
+<td>Array genTextures (uint n)</td>
+</tr>
+
+<tr>
+<td>enum glGetError (void)</td>
+<td></td>
+</tr>
+
+<tr class="gldifferent">
+<td>GetFloatv (GLenum pname, GLfloat *params)</td>
+<td><i>see getParameter</i></td>
+</tr>
+
+<tr class="gldifferent">
+<tr>
+<td>GetIntegerv (GLenum pname, GLint *params)</td>
+<td><i>see getParameter</i></td>
+</tr>
+
+<tr class="gldifferent">
+<td>GetPointerv (GLenum pname, void **params)</td>
+<td><i>see getParameter</i></td>
+</tr>
+
+<tr class="gldifferent">
+<td>GetProgramiv (GLuint program, GLenum pname, GLint *params)</td>
+<td><i>see getProgramParameter</i></td>
+</tr>
+
+<tr class="gldifferent">
+<td>GetProgramInfoLog (GLuint program, GLsizei bufsize, GLsizei *length, char *infolog)</td>
+<td>string getProgramInfoLog (uint program)</td>
+</tr>
+
+<tr class="gldifferent">
+<td>const GLubyte * glGetString (GLenum name)</td>
+<td><i>see getParameter</i></td>
+</tr>
+
+<tr class="gldifferent">
+<td>GetTexParameteriv (GLenum target, GLenum pname, GLint *params)</td>
+<td><i>see getTexParameter</i></td>
+</tr>
+
+<tr class="gldifferent">
+<td>GetTexParameterfv (GLenum target, GLenum pname, GLfloat *params)</td>
+<td><i>see getTexParameter</i></td>
+</tr>
+
+<tr class="gldifferent">
+<td>GetUniformfv (GLuint program, GLint location, GLfloat *params)</td>
+<td><i>TODO</i></td>
+</tr>
+
+<tr class="gldifferent">
+<td>GetUniformiv (GLuint program, GLint location, GLint *params)</td>
+<td><i>TODO</i></td>
+</tr>
+
+<tr class="gldifferent">
+<td>int glGetUniformLocation (GLuint program, const char *name)</td>
+<td>int getUniformLocation (uint program, string name)</td>
+</tr>
+
+<tr class="gldifferent">
+<td>GetVertexAttribfv (GLuint index, GLenum pname, GLfloat *params)</td>
+<td><i>see getVertexAttrib</i></td>
+</tr>
+
+<tr class="gldifferent">
+<td>GetVertexAttribiv (GLuint index, GLenum pname, GLint *params)</td>
+<td><i>see getVertexAttrib</i></td>
+</tr>
+
+<tr class="gldifferent">
+<td>GetVertexAttribPointerv (GLuint index, GLenum pname, void **pointer)</td>
+<td><i>see getVertexAttrib</i></td>
+</tr>
+
+<tr>
+<td>Hint (GLenum target, GLenum mode)</td>
+<td></td>
+</tr>
+
+<tr>
+<td>boolean glIsBuffer (GLuint buffer)</td>
+<td></td>
+</tr>
+
+<tr>
+<td>boolean glIsEnabled (GLenum cap)</td>
+<td></td>
+</tr>
+
+<tr>
+<td>boolean glIsProgram (GLuint program)</td>
+<td></td>
+</tr>
+
+<tr>
+<td>boolean glIsShader (GLuint shader)</td>
+<td></td>
+</tr>
+
+<tr>
+<td>boolean glIsTexture (GLuint texture)</td>
+<td></td>
+</tr>
+
+<tr>
+<td>LineWidth (GLfloat width)</td>
+<td></td>
+</tr>
+
+<tr>
+<td>LinkProgram (GLuint program)</td>
+<td></td>
+</tr>
+
+<tr class="gldifferent">
+<td>PixelStorei (GLenum pname, GLint param)</td>
+<td><i>NONE</i></td>
+</tr>
+
+<tr>
+<td>PointSize (GLfloat size)</td>
+<td></td>
+</tr>
+
+<tr>
+<td>PolygonOffset (GLfloat factor, GLfloat units)</td>
+<td></td>
+</tr>
+
+<tr class="gldifferent">
+<td>ReadPixels (GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, void *pixels)</td>
+<td><i>NONE</i></td>
+</tr>
+
+<tr>
+<td>SampleCoverage (GLclampf value, GLboolean invert)</td>
+<td></td>
+</tr>
+
+<tr>
+<td>Scissor (GLint x, GLint y, GLsizei width, GLsizei height)</td>
+<td></td>
+</tr>
+
+<tr>
+<td>StencilFunc (GLenum func, GLint ref, GLuint mask)</td>
+<td></td>
+</tr>
+
+<tr>
+<td>StencilFuncSeparate (GLenum face, GLenum func, GLint ref, GLuint mask)</td>
+<td></td>
+</tr>
+
+<tr>
+<td>StencilMask (GLuint mask)</td>
+<td></td>
+</tr>
+
+<tr>
+<td>StencilMaskSeparate (GLenum face, GLuint mask)</td>
+<td></td>
+</tr>
+
+<tr>
+<td>StencilOp (GLenum fail, GLenum zfail, GLenum zpass)</td>
+<td></td>
+</tr>
+
+<tr>
+<td>StencilOpSeparate (GLenum face, GLenum fail, GLenum zfail, GLenum zpass)</td>
+<td></td>
+</tr>
+
+<tr class="gldifferent">
+<td>TexImage2D (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const void *pixels)</td>
+<td><i>see texImage2DHTML</i></td>
+</tr>
+
+<tr class="gldifferent">
+<td>TexParameteri (GLenum target, GLenum pname, GLint param)</td>
+<td><i>see texParameter</i></td>
+</tr>
+
+<tr class="gldifferent">
+<td>TexParameterf (GLenum target, GLenum pname, GLfloat param)</td>
+<td><i>see texParameter</i></td>
+</tr>
+
+<tr class="gldifferent">
+<td>TexParameteriv (GLenum target, GLenum pname, const GLint *params)</td>
+<td><i>see texParameter</i></td>
+</tr>
+
+<tr class="gldifferent">
+<td>TexParameterfv (GLenum target, GLenum pname, const GLfloat *params)</td>
+<td><i>see texParameter</i></td>
+</tr>
+
+<tr class="gldifferent">
+<td>TexSubImage2D (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const void *pixels)</td>
+<td><i>see texSubImage2DHTML</i></td>
+</tr>
+
+<tr class="gldifferent">
+<td>Uniform1i (GLint location, GLint x)<br>
+Uniform2i (GLint location, GLint x, GLint y)<br>
+Uniform3i (GLint location, GLint x, GLint y, GLint z)<br>
+Uniform4i (GLint location, GLint x, GLint y, GLint z, GLint w)<br>
+Uniform1iv (GLint location, GLsizei count, const GLint *v)<br>
+Uniform2iv (GLint location, GLsizei count, const GLint *v)<br>
+Uniform3iv (GLint location, GLsizei count, const GLint *v)<br>
+Uniform4iv (GLint location, GLsizei count, const GLint *v)</td>
+<td><i>see uniformi</i></td>
+</tr>
+
+<tr class="gldifferent">
+<td>Uniform1f (GLint location, GLfloat x)<br>
+Uniform2f (GLint location, GLfloat x, GLfloat y)<br>
+Uniform3f (GLint location, GLfloat x, GLfloat y, GLfloat z)<br>
+Uniform4f (GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w)<br>
+Uniform1fv (GLint location, GLsizei count, const GLfloat *v)<br>
+Uniform2fv (GLint location, GLsizei count, const GLfloat *v)<br>
+Uniform3fv (GLint location, GLsizei count, const GLfloat *v)<br>
+Uniform4fv (GLint location, GLsizei count, const GLfloat *v)</td>
+<td><i>see uniformf</i></td>
+</tr>
+
+<tr class="gldifferent">
+<td>UniformMatrix2fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)<br>
+UniformMatrix3fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)<br>
+UniformMatrix4fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)</td>
+<td><i>see uniformMatrix</i></td>
+</tr>
+
+<tr>
+<td>UseProgram (GLuint program)</td>
+<td></td>
+</tr>
+
+<tr>
+<td>ValidateProgram (GLuint program)</td>
+<td></td>
+</tr>
+
+<tr class="gldifferent">
+<td>VertexAttrib1f (GLuint indx, GLfloat x)<br>
+VertexAttrib2f (GLuint indx, GLfloat x, GLfloat y)<br>
+VertexAttrib3f (GLuint indx, GLfloat x, GLfloat y, GLfloat z)<br>
+VertexAttrib4f (GLuint indx, GLfloat x, GLfloat y, GLfloat z, GLfloat w)<br>
+VertexAttrib1fv (GLuint indx, const GLfloat *values)<br>
+VertexAttrib2fv (GLuint indx, const GLfloat *values)<br>
+VertexAttrib3fv (GLuint indx, const GLfloat *values)<br>
+VertexAttrib4fv (GLuint indx, const GLfloat *values)</td>
+<td><i>TODO</i></td>
+</tr>
+
+<tr class="gldifferent">
+<td>VertexAttribPointer (GLuint indx, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const void *ptr)</td>
+<td>vertexAttribPointer (uint index, Object bufferObject)<br>
+vertexAttribPointer (uint index, uint size, uint elementType, Array data)
+</td>
+</tr>
+
+<tr>
+<td>Viewport (GLint x, GLint y, GLsizei width, GLsizei height)</td>
+<td></td>
+</tr>
+
+<tr><td class="glgroup" colspan="2"><b><i>OES_framebuffer_object</i></b></td></tr>
+<tr><td class="gldifferent"><i>TODO</i></td></tr>
+
+<tr><td class="glgroup" colspan="2"><b><i>OES_mapbuffer</i></b></td></tr>
+<tr><td class="gldifferent"><i>NOT SUPPORTED</i></td></tr>
+
+<tr><td class="glgroup" colspan="2"><b><i>OES_texture_3D</i></b></td></tr>
+<tr><td class="gldifferent"><i>TODO</i></td></tr>
+
+<tr><td class="glgroup" colspan="2"><b><i>OES_shader_source</i></b></td></tr>
+<tr><td class="gldifferent"><i>TODO</i></td></tr>
+
+<tr>
+<td>CompileShader (GLuint shader)</td>
+<td></td>
+</tr>
+
+<tr class="gldifferent">
+<td>GetShaderiv (GLuint shader, GLenum pname, GLint *params)</td>
+<td><i>see getShaderParameter</i></td>
+</tr>
+
+<tr class="gldifferent">
+<td>GetShaderInfoLog (GLuint shader, GLsizei bufsize, GLsizei *length, char *infolog)</td>
+<td>string getShaderInfoLog (uint shader)</td>
+</tr>
+
+<tr class="gldifferent">
+<td>GetShaderSource (GLuint shader, GLsizei bufsize, GLsizei *length, char *source)</td>
+<td><i>TODO</i></td>
+</tr>
+
+<tr class="gldifferent">
+<td>ReleaseShaderCompilerOES(void)</td>
+<td><i>NONE</i></td>
+</tr>
+
+<tr class="gldifferent">
+<td>ShaderSource(GLuint shader, GLsizei count, const char **string, const GLint *length)</td>
+<td>shaderSource(uint shader, string source)</td>
+</table>
+
+<tr><td class="glgroup" colspan="2"><b><i>OES_shader_binary</i></b></td></tr>
+<tr><td class="gldifferent"><i>NOT SUPPORTED</i></td></tr>
+
+<h3>API Additions</h3>
+
+<table>
+<tr>
+<td>texImage2DHTML (uint target, DOMImageElement image)<br>
+texImage2DHTML (uint target, int level, DOMImageElement image)</td>
+</tr>
+
+<tr>
+<td>texSubImage2DHTML (uint target, DOMImageElement image, int xoff, int yoff, int width, int height)<br>
+texSubImage2DHTML (uint target, int level, DOMImageElement image, int xoff, int yoff, int width, int height)</td>
+</tr>
+
+<tr>
+<td>getParameter (uint pname)</td>
+</tr>
+
+<tr>
+<td>getBufferParameter (uint target, uint pname)</td>
+</tr>
+
+<tr>
+<td>getProgramParameter</td>
+</tr>
+
+<tr>
+<td>getShaderParameter</td>
+</tr>
+
+<tr>
+<td>getTexParameter</td>
+</tr>
+
+<tr>
+<td>getVertexAttrib</td>
+</tr>
+
+<tr>
+<td>texParameter</td>
+</tr>
+
+<tr>
+<td>uniformf</td>
+</tr>
+
+<tr>
+<td>uniformi</td>
+</tr>
+
+<tr>
+<td>uniformMatrix</td>
+</tr>
+</table>
+
+</body>
--- a/extensions/canvas3d/install.rdf
+++ b/extensions/canvas3d/install.rdf
@@ -11,30 +11,20 @@
     <em:targetApplication>
       <!-- Firefox -->
       <Description>
         <em:id>{ec8030f7-c20a-464f-9b0e-13a3a9e97384}</em:id>
 	<!-- this version needs to be set to the exact version this 
 	     extension was built for, because of the way we're tied
 	     to internal interfaces.
 	  -->
-#ifdef MOZILLA_1_8_BRANCH
-        <em:minVersion>2.0b1</em:minVersion>
-        <em:maxVersion>2.0.*</em:maxVersion>
-#else
-        <em:minVersion>3.0a1</em:minVersion>
-        <em:maxVersion>3.0a1</em:maxVersion>
-#endif
+        <em:minVersion>3.0a4pre</em:minVersion>
+        <em:maxVersion>3.0a4pre</em:maxVersion>
       </Description>
     </em:targetApplication>
 	
     <!-- front-end metadata -->
     <em:creator>Vladimir Vukicevic/mozilla.com</em:creator>
-#ifdef MOZILLA_1_8_BRANCH
-    <em:name>Canvas 3D (Gecko 1.8.1)</em:name>
-    <em:description>Canvas 3D context(s) for Gecko 1.8.1</em:description>
-#else
     <em:name>Canvas 3D (Gecko 1.9)</em:name>
     <em:description>Canvas 3D context(s) for Gecko 1.9</em:description>
-#endif
     <em:homepageURL>http://people.mozilla.com/~vladimir/canvas3d/</em:homepageURL>
   </Description>
 </RDF>
--- a/extensions/canvas3d/public/Makefile.in
+++ b/extensions/canvas3d/public/Makefile.in
@@ -41,15 +41,17 @@ topsrcdir        = @top_srcdir@
 srcdir           = @srcdir@
 VPATH            = @srcdir@
 
 include $(DEPTH)/config/autoconf.mk
 
 MODULE		= canvas3d
 XPI_NAME	= canvas3d
 
-XPIDLSRCS	= nsICanvasRenderingContextGLES11.idl \
-		  $(NULL)
-
-#		  nsICanvasRenderingContextGLES20.idl
+XPIDLSRCS	= \
+	nsICanvasRenderingContextGL.idl \
+	nsICanvasRenderingContextGLWeb20.idl \
+	nsICanvasRenderingContextGLES11.idl \
+	nsICanvasGLPrivate.idl \
+	$(NULL)
 
 include $(topsrcdir)/config/rules.mk
 
new file mode 100644
--- /dev/null
+++ b/extensions/canvas3d/public/nsICanvasGLPrivate.idl
@@ -0,0 +1,53 @@
+/* -*- 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"
+
+/* These are private interface that's used to identify
+ * specific concrete classes so we know what we can cast.
+ */
+
+[scriptable, uuid(eba2aa03-ae19-46e2-bad7-6b966037e22c)]
+interface nsICanvasGLBuffer : nsISupports
+{
+};
+
+[scriptable, uuid(27310aab-1988-43e8-882e-6293c8c9df60)]
+interface nsICanvasGLTexture : nsISupports
+{
+};
new file mode 100644
--- /dev/null
+++ b/extensions/canvas3d/public/nsICanvasRenderingContextGL.idl
@@ -0,0 +1,653 @@
+/* -*- 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;
+
+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);
+};
+
+[scriptable, uuid(0f3d8dae-7d43-490b-93e9-5ff908ac6ff5)]
+interface nsICanvasRenderingContextGL : nsISupports
+{
+  readonly attribute nsIDOMHTMLCanvasElement canvas;
+
+  /**
+   ** GL constants
+   **/
+
+  /* types */
+  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 TWO_BYTES                      = 0x1407;
+  const PRUint32 THREE_BYTES                    = 0x1408;
+  const PRUint32 FOUR_BYTES                     = 0x1409;
+  const PRUint32 DOUBLE                         = 0x140A;
+
+  /* ClearBufferMask */
+  const PRUint32 DEPTH_BUFFER_BIT               = 0x00000100;
+  const PRUint32 STENCIL_BUFFER_BIT             = 0x00000400;
+  const PRUint32 COLOR_BUFFER_BIT               = 0x00004000;
+
+  /* BeginMode */
+  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;
+
+  /* AlphaFunction */
+  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;
+
+  /* BlendingFactorDest */
+  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;
+
+  /* BlendingFactorSrc */
+  /*    ZERO */
+  /*    ONE */
+  const PRUint32 DST_COLOR                      = 0x0306;
+  const PRUint32 ONE_MINUS_DST_COLOR            = 0x0307;
+  const PRUint32 SRC_ALPHA_SATURATE             = 0x0308;
+  /*    SRC_ALPHA */
+  /*    ONE_MINUS_SRC_ALPHA */
+  /*    DST_ALPHA */
+  /*    ONE_MINUS_DST_ALPHA */
+
+  /* BlendEquationSeperate */
+  const PRUint32 FUNC_ADD = 0x8006;
+  const PRUint32 BLEND_EQUATION = 0x8009;
+  const PRUint32 BLEND_EQUATION_RGB = 0x8009;
+  const PRUint32 BLEND_EQUATION_ALPHA = 0x883D;
+
+  /* BlendSubtract */
+  const PRUint32 FUNC_SUBTRACT = 0x800A;
+  const PRUint32 FUNC_REVERSE_SUBTRACT = 0x800B;
+
+  /* Separate Blend Functions i.e. GL_OES_blend_func_seperate */
+  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;
+
+  /* Buffer Objects */
+  const PRUint32 BUFFER_SIZE = 0x8764;
+  const PRUint32 BUFFER_USAGE = 0x8765;
+  const PRUint32 BUFFER_ACCESS = 0x88BB;
+
+  const PRUint32 CURRENT_VERTEX_ATTRIB = 0x8626;
+
+  /* ClipPlaneName */
+  const PRUint32 CLIP_PLANE0                    = 0x3000;
+  const PRUint32 CLIP_PLANE1                    = 0x3001;
+  const PRUint32 CLIP_PLANE2                    = 0x3002;
+  const PRUint32 CLIP_PLANE3                    = 0x3003;
+  const PRUint32 CLIP_PLANE4                    = 0x3004;
+  const PRUint32 CLIP_PLANE5                    = 0x3005;
+
+  /* ColorMaterialFace */
+  /*    FRONT_AND_BACK */
+
+  /* ColorMaterialParameter */
+  /*    AMBIENT_AND_DIFFUSE */
+
+  /* CullFaceMode */
+  const PRUint32 FRONT                          = 0x0404;
+  const PRUint32 BACK                           = 0x0405;
+  const PRUint32 FRONT_AND_BACK                 = 0x0408;
+
+  /* DepthFunction */
+  /*    NEVER */
+  /*    LESS */
+  /*    EQUAL */
+  /*    LEQUAL */
+  /*    GREATER */
+  /*    NOTEQUAL */
+  /*    GEQUAL */
+  /*    ALWAYS */
+
+  /* EnableCap */
+  const PRUint32 FOG                            = 0x0B60;
+  const PRUint32 LIGHTING                       = 0x0B50;
+  const PRUint32 TEXTURE_2D                     = 0x0DE1;
+  const PRUint32 CULL_FACE                      = 0x0B44;
+  const PRUint32 ALPHA_TEST                     = 0x0BC0;
+  const PRUint32 BLEND                          = 0x0BE2;
+  const PRUint32 COLOR_LOGIC_OP                 = 0x0BF2;
+  const PRUint32 DITHER                         = 0x0BD0;
+  const PRUint32 STENCIL_TEST                   = 0x0B90;
+  const PRUint32 DEPTH_TEST                     = 0x0B71;
+  /*             LIGHT0 */
+  /*             LIGHT1 */
+  /*             LIGHT2 */
+  /*             LIGHT3 */
+  /*             LIGHT4 */
+  /*             LIGHT5 */
+  /*             LIGHT6 */
+  /*             LIGHT7 */
+  const PRUint32 POINT_SMOOTH                   = 0x0B10;
+  const PRUint32 LINE_SMOOTH                    = 0x0B20;
+  const PRUint32 SCISSOR_TEST                   = 0x0C11;
+  const PRUint32 COLOR_MATERIAL                 = 0x0B57;
+  const PRUint32 NORMALIZE                      = 0x0BA1;
+  const PRUint32 RESCALE_NORMAL                 = 0x803A;
+  const PRUint32 POLYGON_OFFSET_FILL            = 0x8037;
+  const PRUint32 VERTEX_ARRAY                   = 0x8074;
+  const PRUint32 NORMAL_ARRAY                   = 0x8075;
+  const PRUint32 COLOR_ARRAY                    = 0x8076;
+  const PRUint32 TEXTURE_COORD_ARRAY            = 0x8078;
+  const PRUint32 MULTISAMPLE                    = 0x809D;
+  const PRUint32 SAMPLE_ALPHA_TO_COVERAGE       = 0x809E;
+  const PRUint32 SAMPLE_ALPHA_TO_ONE            = 0x809F;
+  const PRUint32 SAMPLE_COVERAGE                = 0x80A0;
+
+  /* ErrorCode */
+  const PRUint32 NO_ERROR                       = 0;
+  const PRUint32 INVALID_ENUM                   = 0x0500;
+  const PRUint32 INVALID_VALUE                  = 0x0501;
+  const PRUint32 INVALID_OPERATION              = 0x0502;
+  const PRUint32 STACK_OVERFLOW                 = 0x0503;
+  const PRUint32 STACK_UNDERFLOW                = 0x0504;
+  const PRUint32 OUT_OF_MEMORY                  = 0x0505;
+
+  /* FogMode */
+  /*             LINEAR */
+  const PRUint32 EXP                            = 0x0800;
+  const PRUint32 EXP2                           = 0x0801;
+
+  /* FogParameter */
+  const PRUint32 FOG_DENSITY                    = 0x0B62;
+  const PRUint32 FOG_START                      = 0x0B63;
+  const PRUint32 FOG_END                        = 0x0B64;
+  const PRUint32 FOG_MODE                       = 0x0B65;
+  const PRUint32 FOG_COLOR                      = 0x0B66;
+
+  /* FrontFaceDirection */
+  const PRUint32 CW                             = 0x0900;
+  const PRUint32 CCW                            = 0x0901;
+
+  /* GetPName */
+  const PRUint32 CURRENT_COLOR                  = 0x0B00;
+  const PRUint32 CURRENT_NORMAL                 = 0x0B02;
+  const PRUint32 CURRENT_TEXTURE_COORDS         = 0x0B03;
+  const PRUint32 POINT_SIZE                     = 0x0B11;
+  const PRUint32 POINT_SIZE_MIN                 = 0x8126;
+  const PRUint32 POINT_SIZE_MAX                 = 0x8127;
+  const PRUint32 POINT_FADE_THRESHOLD_SIZE      = 0x8128;
+  const PRUint32 POINT_DISTANCE_ATTENUATION     = 0x8129;
+  const PRUint32 SMOOTH_POINT_SIZE_RANGE        = 0x0B12;
+  const PRUint32 LINE_WIDTH                     = 0x0B21;
+  const PRUint32 SMOOTH_LINE_WIDTH_RANGE        = 0x0B22;
+  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 SHADE_MODEL                    = 0x0B54;
+  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_VALUE_MASK             = 0x0B93;
+  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_WRITEMASK              = 0x0B98;
+  const PRUint32 MATRIX_MODE                    = 0x0BA0;
+  // VIEWPORT -> VIEWPORT_VALUE, because viewport() conflicts
+  const PRUint32 VIEWPORT_VALUE                 = 0x0BA2;
+  const PRUint32 MODELVIEW_STACK_DEPTH          = 0x0BA3;
+  const PRUint32 PROJECTION_STACK_DEPTH         = 0x0BA4;
+  const PRUint32 TEXTURE_STACK_DEPTH            = 0x0BA5;
+  const PRUint32 MODELVIEW_MATRIX               = 0x0BA6;
+  const PRUint32 PROJECTION_MATRIX              = 0x0BA7;
+  const PRUint32 TEXTURE_MATRIX                 = 0x0BA8;
+  const PRUint32 ALPHA_TEST_FUNC                = 0x0BC1;
+  const PRUint32 ALPHA_TEST_REF                 = 0x0BC2;
+  const PRUint32 BLEND_DST                      = 0x0BE0;
+  const PRUint32 BLEND_SRC                      = 0x0BE1;
+  const PRUint32 LOGIC_OP_MODE                  = 0x0BF0;
+  const PRUint32 SCISSOR_BOX                    = 0x0C10;
+  /*             SCISSOR_TEST */
+  const PRUint32 COLOR_CLEAR_VALUE              = 0x0C22;
+  const PRUint32 COLOR_WRITEMASK                = 0x0C23;
+  const PRUint32 UNPACK_ALIGNMENT               = 0x0CF5;
+  const PRUint32 PACK_ALIGNMENT                 = 0x0D05;
+  const PRUint32 MAX_LIGHTS                     = 0x0D31;
+  const PRUint32 MAX_CLIP_PLANES                = 0x0D32;
+  const PRUint32 MAX_TEXTURE_SIZE               = 0x0D33;
+  const PRUint32 MAX_MODELVIEW_STACK_DEPTH      = 0x0D36;
+  const PRUint32 MAX_PROJECTION_STACK_DEPTH     = 0x0D38;
+  const PRUint32 MAX_TEXTURE_STACK_DEPTH        = 0x0D39;
+  const PRUint32 MAX_VIEWPORT_DIMS              = 0x0D3A;
+  const PRUint32 MAX_ELEMENTS_VERTICES          = 0x80E8;
+  const PRUint32 MAX_ELEMENTS_INDICES           = 0x80E9;
+  const PRUint32 MAX_TEXTURE_UNITS              = 0x84E2;
+  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;
+  //             POLYGON_OFFSET_FILL            = 0x8037;
+  const PRUint32 POLYGON_OFFSET_FACTOR          = 0x8038;
+  const PRUint32 TEXTURE_BINDING_2D             = 0x8069;
+  const PRUint32 VERTEX_ARRAY_SIZE              = 0x807A;
+  const PRUint32 VERTEX_ARRAY_TYPE              = 0x807B;
+  const PRUint32 VERTEX_ARRAY_STRIDE            = 0x807C;
+  const PRUint32 NORMAL_ARRAY_TYPE              = 0x807E;
+  const PRUint32 NORMAL_ARRAY_STRIDE            = 0x807F;
+  const PRUint32 COLOR_ARRAY_SIZE               = 0x8081;
+  const PRUint32 COLOR_ARRAY_TYPE               = 0x8082;
+  const PRUint32 COLOR_ARRAY_STRIDE             = 0x8083;
+  const PRUint32 TEXTURE_COORD_ARRAY_SIZE       = 0x8088;
+  const PRUint32 TEXTURE_COORD_ARRAY_TYPE       = 0x8089;
+  const PRUint32 TEXTURE_COORD_ARRAY_STRIDE     = 0x808A;
+  const PRUint32 VERTEX_ARRAY_POINTER           = 0x808E;
+  const PRUint32 NORMAL_ARRAY_POINTER           = 0x808F;
+  const PRUint32 COLOR_ARRAY_POINTER            = 0x8090;
+  const PRUint32 TEXTURE_COORD_ARRAY_POINTER    = 0x8092;
+  const PRUint32 SAMPLE_BUFFERS                 = 0x80A8;
+  const PRUint32 SAMPLES                        = 0x80A9;
+  const PRUint32 SAMPLE_COVERAGE_VALUE          = 0x80AA;
+  const PRUint32 SAMPLE_COVERAGE_INVERT         = 0x80AB;
+
+  /* GetTextureParameter */
+  /*             TEXTURE_MAG_FILTER */
+  /*             TEXTURE_MIN_FILTER */
+  /*             TEXTURE_WRAP_S */
+  /*             TEXTURE_WRAP_T */
+  
+  /* HintMode */
+  const PRUint32 DONT_CARE                      = 0x1100;
+  const PRUint32 FASTEST                        = 0x1101;
+  const PRUint32 NICEST                         = 0x1102;
+
+  /* HintTarget */
+  const PRUint32 PERSPECTIVE_CORRECTION_HINT    = 0x0C50;
+  const PRUint32 POINT_SMOOTH_HINT              = 0x0C51;
+  const PRUint32 LINE_SMOOTH_HINT               = 0x0C52;
+  const PRUint32 POLYGON_SMOOTH_HINT            = 0x0C53;
+  const PRUint32 FOG_HINT                       = 0x0C54;
+  const PRUint32 GENERATE_MIPMAP_HINT           = 0x8192;
+
+  /* LightModelParameter */
+  const PRUint32 LIGHT_MODEL_AMBIENT            = 0x0B53;
+  const PRUint32 LIGHT_MODEL_TWO_SIDE           = 0x0B52;
+  const PRUint32 LIGHT_MODEL_LOCAL_VIEWER       = 0x0B51;
+  const PRUint32 LIGHT_MODEL_COLOR_CONTROL      = 0x81F8;
+
+  /* LightParameter */
+  const PRUint32 AMBIENT                        = 0x1200;
+  const PRUint32 DIFFUSE                        = 0x1201;
+  const PRUint32 SPECULAR                       = 0x1202;
+  const PRUint32 POSITION                       = 0x1203;
+  const PRUint32 SPOT_DIRECTION                 = 0x1204;
+  const PRUint32 SPOT_EXPONENT                  = 0x1205;
+  const PRUint32 SPOT_CUTOFF                    = 0x1206;
+  const PRUint32 CONSTANT_ATTENUATION           = 0x1207;
+  const PRUint32 LINEAR_ATTENUATION             = 0x1208;
+  const PRUint32 QUADRATIC_ATTENUATION          = 0x1209;
+
+  /* LogicOp */
+  /* CLEAR -> CLEAR_OP, because clear() is a method */
+  const PRUint32 CLEAR_OP                       = 0x1500;
+  const PRUint32 AND                            = 0x1501;
+  const PRUint32 AND_REVERSE                    = 0x1502;
+  const PRUint32 COPY                           = 0x1503;
+  const PRUint32 AND_INVERTED                   = 0x1504;
+  const PRUint32 NOOP                           = 0x1505;
+  const PRUint32 XOR                            = 0x1506;
+  const PRUint32 OR                             = 0x1507;
+  const PRUint32 NOR                            = 0x1508;
+  const PRUint32 EQUIV                          = 0x1509;
+  const PRUint32 INVERT                         = 0x150A;
+  const PRUint32 OR_REVERSE                     = 0x150B;
+  const PRUint32 COPY_INVERTED                  = 0x150C;
+  const PRUint32 OR_INVERTED                    = 0x150D;
+  const PRUint32 NAND                           = 0x150E;
+  const PRUint32 SET                            = 0x150F;
+
+  /* MaterialFace */
+  /*             FRONT_AND_BACK */
+
+  /* MaterialParameter */
+  const PRUint32 EMISSION                       = 0x1600;
+  const PRUint32 SHININESS                      = 0x1601;
+  const PRUint32 AMBIENT_AND_DIFFUSE            = 0x1602;
+
+  /* MatrixMode */
+  const PRUint32 MODELVIEW                      = 0x1700;
+  const PRUint32 PROJECTION                     = 0x1701;
+  const PRUint32 TEXTURE                        = 0x1702;
+
+  /* LightName */
+  const PRUint32 LIGHT0                         = 0x4000;
+  const PRUint32 LIGHT1                         = 0x4001;
+  const PRUint32 LIGHT2                         = 0x4002;
+  const PRUint32 LIGHT3                         = 0x4003;
+  const PRUint32 LIGHT4                         = 0x4004;
+  const PRUint32 LIGHT5                         = 0x4005;
+  const PRUint32 LIGHT6                         = 0x4006;
+  const PRUint32 LIGHT7                         = 0x4007;
+
+  /* Shaders */
+  const PRUint32 VERTEX_PROGRAM_POINT_SIZE = 0x8642;
+  //const PRUint32 VERTEX_ATTRIB_ARRAY_NORMALIZED = 0x886A;
+
+  const PRUint32 FRAGMENT_SHADER = 0x8B30;
+  const PRUint32 VERTEX_SHADER = 0x8B31;
+  const PRUint32 MAX_VERTEX_ATTRIBS = 0x8869;
+  const PRUint32 MAX_VERTEX_UNIFORM_COMPONENTS = 0x8B4A;
+  const PRUint32 MAX_VARYING_FLOATS = 0x8B4B;
+  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_COMPONENTS = 0x8B49;
+  const PRUint32 SHADER_TYPE = 0x8B4F;
+  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_1D = 0x8B5D;
+  const PRUint32 SAMPLER_2D = 0x8B5E;
+  const PRUint32 SAMPLER_3D = 0x8B5F;
+  const PRUint32 SAMPLER_CUBE = 0x8B60;
+  const PRUint32 SAMPLER_1D_SHADOW = 0x8B61;
+  const PRUint32 SAMPLER_2D_SHADOW = 0x8B62;
+  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;
+
+
+  /* ShadingModel */
+  const PRUint32 FLAT                           = 0x1D00;
+  const PRUint32 SMOOTH                         = 0x1D01;
+
+  /* StencilFunction */
+  /*             NEVER */
+  /*             LESS */
+  /*             EQUAL */
+  /*             LEQUAL */
+  /*             GREATER */
+  /*             NOTEQUAL */
+  /*             GEQUAL */
+  /*             ALWAYS */
+
+  /* StencilOp */
+  /*             ZERO */
+  const PRUint32 KEEP                           = 0x1E00;
+  const PRUint32 REPLACE                        = 0x1E01;
+  const PRUint32 INCR                           = 0x1E02;
+  const PRUint32 DECR                           = 0x1E03;
+  /*             INVERT */
+
+  /* StringName */
+  const PRUint32 VENDOR                         = 0x1F00;
+  const PRUint32 RENDERER                       = 0x1F01;
+  const PRUint32 VERSION                        = 0x1F02;
+  const PRUint32 EXTENSIONS                     = 0x1F03;
+
+  /* TextureEnvMode */
+  const PRUint32 MODULATE                       = 0x2100;
+  const PRUint32 DECAL                          = 0x2101;
+  /*             BLEND */
+  const PRUint32 ADD                            = 0x0104;
+  //             REPLACE
+  /*             COMBINE */
+
+  /* TextureEnvParameter */
+  const PRUint32 TEXTURE_ENV_MODE               = 0x2200;
+  const PRUint32 TEXTURE_ENV_COLOR              = 0x2201;
+
+  /* TextureEnvTarget */
+  const PRUint32 TEXTURE_ENV                    = 0x2300;
+
+  /* TextureMagFilter */
+  const PRUint32 NEAREST                        = 0x2600;
+  const PRUint32 LINEAR                         = 0x2601;
+
+  /* TextureMinFilter */
+  /*             NEAREST */
+  /*             LINEAR */
+  const PRUint32 NEAREST_MIPMAP_NEAREST         = 0x2700;
+  const PRUint32 LINEAR_MIPMAP_NEAREST          = 0x2701;
+  const PRUint32 NEAREST_MIPMAP_LINEAR          = 0x2702;
+  const PRUint32 LINEAR_MIPMAP_LINEAR           = 0x2703;
+
+  /* TextureParameterName */
+  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 GENERATE_MIPMAP                = 0x8191;
+
+  /* TextureUnit */
+  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 CLIENT_ACTIVE_TEXTURE          = 0x84E1;
+
+  /* TextureWrapMode */
+  const PRUint32 REPEAT                         = 0x2901;
+  const PRUint32 CLAMP_TO_EDGE                  = 0x812F;
+
+  /* Texture combine + dot3 */
+  const PRUint32 SUBTRACT                       = 0x84E7;
+  const PRUint32 COMBINE                        = 0x8570;
+  const PRUint32 COMBINE_RGB                    = 0x8571;
+  const PRUint32 COMBINE_ALPHA                  = 0x8572;
+  const PRUint32 RGB_SCALE                      = 0x8573;
+  const PRUint32 ADD_SIGNED                     = 0x8574;
+  const PRUint32 INTERPOLATE                    = 0x8575;
+  const PRUint32 CONSTANT                       = 0x8576;
+  const PRUint32 PRIMARY_COLOR                  = 0x8577;
+  const PRUint32 PREVIOUS                       = 0x8578;
+  const PRUint32 OPERAND0_RGB                   = 0x8590;
+  const PRUint32 OPERAND1_RGB                   = 0x8591;
+  const PRUint32 OPERAND2_RGB                   = 0x8592;
+  const PRUint32 OPERAND0_ALPHA                 = 0x8598;
+  const PRUint32 OPERAND1_ALPHA                 = 0x8599;
+  const PRUint32 OPERAND2_ALPHA                 = 0x859A;
+
+  const PRUint32 ALPHA_SCALE                    = 0x0D1C;
+
+  const PRUint32 SRC0_RGB                       = 0x8580;
+  const PRUint32 SRC1_RGB                       = 0x8581;
+  const PRUint32 SRC2_RGB                       = 0x8582;
+  const PRUint32 SRC0_ALPHA                     = 0x8588;
+  const PRUint32 SRC1_ALPHA                     = 0x8589;
+  const PRUint32 SRC2_ALPHA                     = 0x858A;
+
+  const PRUint32 DOT3_RGB                       = 0x86AE;
+  const PRUint32 DOT3_RGBA                      = 0x86AF;
+
+  /* Vertex Arrays */
+  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;
+
+  /* Buffers */
+  const PRUint32 STATIC_DRAW                    = 0x88E4;
+  const PRUint32 DYNAMIC_DRAW                   = 0x88E8;
+  const PRUint32 ARRAY_BUFFER                   = 0x8892;
+  const PRUint32 ELEMENT_ARRAY_BUFFER           = 0x8893;
+  const PRUint32 ARRAY_BUFFER_BINDING = 0x8894;
+  const PRUint32 ELEMENT_ARRAY_BUFFER_BINDING = 0x8895;
+
+  /* Extensions */
+  const PRUint32 TEXTURE_RECTANGLE              = 0x84F5;
+  const PRUint32 TEXTURE_BINDING_RECTANGLE      = 0x84F6;
+  const PRUint32 MAX_RECTANGLE_TEXTURE_SIZE     = 0x84F8;
+
+  const PRUint32 TEXTURE_MAX_ANISOTROPY         = 0x84FE;
+  const PRUint32 MAX_TEXTURE_MAX_ANISOTROPY     = 0x84FF;
+
+
+  // Other
+  void swapBuffers ();
+
+};
\ No newline at end of file
--- a/extensions/canvas3d/public/nsICanvasRenderingContextGLES11.idl
+++ b/extensions/canvas3d/public/nsICanvasRenderingContextGLES11.idl
@@ -31,547 +31,24 @@
  * 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"
+#include "nsICanvasRenderingContextGL.idl"
 
 interface nsIDOMHTMLElement;
 interface nsIDOMHTMLCanvasElement;
 
-interface nsICanvasRenderingContextGLES11;
-
-[scriptable, uuid(7c5ec0b3-a64c-4d9e-a8d5-acb574269dc4)]
-interface nsICanvasRenderingContextGLES11Buffer : nsISupports
-{
-  readonly attribute nsICanvasRenderingContextGLES11 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 nsICanvasRenderingContextGLES11Texture : nsISupports
-{
-  readonly attribute nsICanvasRenderingContextGLES11 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);
-};
-
 [scriptable, uuid(619a102d-6c58-4660-ba35-60d9b8de92ab)]
-interface nsICanvasRenderingContextGLES11 : nsISupports
+interface nsICanvasRenderingContextGLES11 : nsICanvasRenderingContextGL
 {
-  readonly attribute nsIDOMHTMLCanvasElement canvas;
-
-  /**
-   ** GL constants
-   **/
-
-  /* types */
-  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 TWO_BYTES                      = 0x1407;
-  const PRUint32 THREE_BYTES                    = 0x1408;
-  const PRUint32 FOUR_BYTES                     = 0x1409;
-  const PRUint32 DOUBLE                         = 0x140A;
-
-  /* ClearBufferMask */
-  const PRUint32 DEPTH_BUFFER_BIT               = 0x00000100;
-  const PRUint32 STENCIL_BUFFER_BIT             = 0x00000400;
-  const PRUint32 COLOR_BUFFER_BIT               = 0x00004000;
-
-  /* BeginMode */
-  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;
-
-  /* AlphaFunction */
-  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;
-
-  /* BlendingFactorDest */
-  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;
-
-  /* BlendingFactorSrc */
-  /*    ZERO */
-  /*    ONE */
-  const PRUint32 DST_COLOR                      = 0x0306;
-  const PRUint32 ONE_MINUS_DST_COLOR            = 0x0307;
-  const PRUint32 SRC_ALPHA_SATURATE             = 0x0308;
-  /*    SRC_ALPHA */
-  /*    ONE_MINUS_SRC_ALPHA */
-  /*    DST_ALPHA */
-  /*    ONE_MINUS_DST_ALPHA */
-
-  /* ClipPlaneName */
-  const PRUint32 CLIP_PLANE0                    = 0x3000;
-  const PRUint32 CLIP_PLANE1                    = 0x3001;
-  const PRUint32 CLIP_PLANE2                    = 0x3002;
-  const PRUint32 CLIP_PLANE3                    = 0x3003;
-  const PRUint32 CLIP_PLANE4                    = 0x3004;
-  const PRUint32 CLIP_PLANE5                    = 0x3005;
-
-  /* ColorMaterialFace */
-  /*    FRONT_AND_BACK */
-
-  /* ColorMaterialParameter */
-  /*    AMBIENT_AND_DIFFUSE */
-
-  /* CullFaceMode */
-  const PRUint32 FRONT                          = 0x0404;
-  const PRUint32 BACK                           = 0x0405;
-  const PRUint32 FRONT_AND_BACK                 = 0x0408;
-
-  /* DepthFunction */
-  /*    NEVER */
-  /*    LESS */
-  /*    EQUAL */
-  /*    LEQUAL */
-  /*    GREATER */
-  /*    NOTEQUAL */
-  /*    GEQUAL */
-  /*    ALWAYS */
-
-  /* EnableCap */
-  const PRUint32 FOG                            = 0x0B60;
-  const PRUint32 LIGHTING                       = 0x0B50;
-  const PRUint32 TEXTURE_2D                     = 0x0DE1;
-  const PRUint32 CULL_FACE                      = 0x0B44;
-  const PRUint32 ALPHA_TEST                     = 0x0BC0;
-  const PRUint32 BLEND                          = 0x0BE2;
-  const PRUint32 COLOR_LOGIC_OP                 = 0x0BF2;
-  const PRUint32 DITHER                         = 0x0BD0;
-  const PRUint32 STENCIL_TEST                   = 0x0B90;
-  const PRUint32 DEPTH_TEST                     = 0x0B71;
-  /*             LIGHT0 */
-  /*             LIGHT1 */
-  /*             LIGHT2 */
-  /*             LIGHT3 */
-  /*             LIGHT4 */
-  /*             LIGHT5 */
-  /*             LIGHT6 */
-  /*             LIGHT7 */
-  const PRUint32 POINT_SMOOTH                   = 0x0B10;
-  const PRUint32 LINE_SMOOTH                    = 0x0B20;
-  const PRUint32 SCISSOR_TEST                   = 0x0C11;
-  const PRUint32 COLOR_MATERIAL                 = 0x0B57;
-  const PRUint32 NORMALIZE                      = 0x0BA1;
-  const PRUint32 RESCALE_NORMAL                 = 0x803A;
-  const PRUint32 POLYGON_OFFSET_FILL            = 0x8037;
-  const PRUint32 VERTEX_ARRAY                   = 0x8074;
-  const PRUint32 NORMAL_ARRAY                   = 0x8075;
-  const PRUint32 COLOR_ARRAY                    = 0x8076;
-  const PRUint32 TEXTURE_COORD_ARRAY            = 0x8078;
-  const PRUint32 MULTISAMPLE                    = 0x809D;
-  const PRUint32 SAMPLE_ALPHA_TO_COVERAGE       = 0x809E;
-  const PRUint32 SAMPLE_ALPHA_TO_ONE            = 0x809F;
-  const PRUint32 SAMPLE_COVERAGE                = 0x80A0;
-
-  /* ErrorCode */
-  const PRUint32 NO_ERROR                       = 0;
-  const PRUint32 INVALID_ENUM                   = 0x0500;
-  const PRUint32 INVALID_VALUE                  = 0x0501;
-  const PRUint32 INVALID_OPERATION              = 0x0502;
-  const PRUint32 STACK_OVERFLOW                 = 0x0503;
-  const PRUint32 STACK_UNDERFLOW                = 0x0504;
-  const PRUint32 OUT_OF_MEMORY                  = 0x0505;
-
-  /* FogMode */
-  /*             LINEAR */
-  const PRUint32 EXP                            = 0x0800;
-  const PRUint32 EXP2                           = 0x0801;
-
-  /* FogParameter */
-  const PRUint32 FOG_DENSITY                    = 0x0B62;
-  const PRUint32 FOG_START                      = 0x0B63;
-  const PRUint32 FOG_END                        = 0x0B64;
-  const PRUint32 FOG_MODE                       = 0x0B65;
-  const PRUint32 FOG_COLOR                      = 0x0B66;
-
-  /* FrontFaceDirection */
-  const PRUint32 CW                             = 0x0900;
-  const PRUint32 CCW                            = 0x0901;
-
-  /* GetPName */
-  const PRUint32 CURRENT_COLOR                  = 0x0B00;
-  const PRUint32 CURRENT_NORMAL                 = 0x0B02;
-  const PRUint32 CURRENT_TEXTURE_COORDS         = 0x0B03;
-  const PRUint32 POINT_SIZE                     = 0x0B11;
-  const PRUint32 POINT_SIZE_MIN                 = 0x8126;
-  const PRUint32 POINT_SIZE_MAX                 = 0x8127;
-  const PRUint32 POINT_FADE_THRESHOLD_SIZE      = 0x8128;
-  const PRUint32 POINT_DISTANCE_ATTENUATION     = 0x8129;
-  const PRUint32 SMOOTH_POINT_SIZE_RANGE        = 0x0B12;
-  const PRUint32 LINE_WIDTH                     = 0x0B21;
-  const PRUint32 SMOOTH_LINE_WIDTH_RANGE        = 0x0B22;
-  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 SHADE_MODEL                    = 0x0B54;
-  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_VALUE_MASK             = 0x0B93;
-  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_WRITEMASK              = 0x0B98;
-  const PRUint32 MATRIX_MODE                    = 0x0BA0;
-  // VIEWPORT -> VIEWPORT_VALUE, because viewport() conflicts
-  const PRUint32 VIEWPORT_VALUE                 = 0x0BA2;
-  const PRUint32 MODELVIEW_STACK_DEPTH          = 0x0BA3;
-  const PRUint32 PROJECTION_STACK_DEPTH         = 0x0BA4;
-  const PRUint32 TEXTURE_STACK_DEPTH            = 0x0BA5;
-  const PRUint32 MODELVIEW_MATRIX               = 0x0BA6;
-  const PRUint32 PROJECTION_MATRIX              = 0x0BA7;
-  const PRUint32 TEXTURE_MATRIX                 = 0x0BA8;
-  const PRUint32 ALPHA_TEST_FUNC                = 0x0BC1;
-  const PRUint32 ALPHA_TEST_REF                 = 0x0BC2;
-  const PRUint32 BLEND_DST                      = 0x0BE0;
-  const PRUint32 BLEND_SRC                      = 0x0BE1;
-  const PRUint32 LOGIC_OP_MODE                  = 0x0BF0;
-  const PRUint32 SCISSOR_BOX                    = 0x0C10;
-  /*             SCISSOR_TEST */
-  const PRUint32 COLOR_CLEAR_VALUE              = 0x0C22;
-  const PRUint32 COLOR_WRITEMASK                = 0x0C23;
-  const PRUint32 UNPACK_ALIGNMENT               = 0x0CF5;
-  const PRUint32 PACK_ALIGNMENT                 = 0x0D05;
-  const PRUint32 MAX_LIGHTS                     = 0x0D31;
-  const PRUint32 MAX_CLIP_PLANES                = 0x0D32;
-  const PRUint32 MAX_TEXTURE_SIZE               = 0x0D33;
-  const PRUint32 MAX_MODELVIEW_STACK_DEPTH      = 0x0D36;
-  const PRUint32 MAX_PROJECTION_STACK_DEPTH     = 0x0D38;
-  const PRUint32 MAX_TEXTURE_STACK_DEPTH        = 0x0D39;
-  const PRUint32 MAX_VIEWPORT_DIMS              = 0x0D3A;
-  const PRUint32 MAX_ELEMENTS_VERTICES          = 0x80E8;
-  const PRUint32 MAX_ELEMENTS_INDICES           = 0x80E9;
-  const PRUint32 MAX_TEXTURE_UNITS              = 0x84E2;
-  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;
-  //             POLYGON_OFFSET_FILL            = 0x8037;
-  const PRUint32 POLYGON_OFFSET_FACTOR          = 0x8038;
-  const PRUint32 TEXTURE_BINDING_2D             = 0x8069;
-  const PRUint32 VERTEX_ARRAY_SIZE              = 0x807A;
-  const PRUint32 VERTEX_ARRAY_TYPE              = 0x807B;
-  const PRUint32 VERTEX_ARRAY_STRIDE            = 0x807C;
-  const PRUint32 NORMAL_ARRAY_TYPE              = 0x807E;
-  const PRUint32 NORMAL_ARRAY_STRIDE            = 0x807F;
-  const PRUint32 COLOR_ARRAY_SIZE               = 0x8081;
-  const PRUint32 COLOR_ARRAY_TYPE               = 0x8082;
-  const PRUint32 COLOR_ARRAY_STRIDE             = 0x8083;
-  const PRUint32 TEXTURE_COORD_ARRAY_SIZE       = 0x8088;
-  const PRUint32 TEXTURE_COORD_ARRAY_TYPE       = 0x8089;
-  const PRUint32 TEXTURE_COORD_ARRAY_STRIDE     = 0x808A;
-  const PRUint32 VERTEX_ARRAY_POINTER           = 0x808E;
-  const PRUint32 NORMAL_ARRAY_POINTER           = 0x808F;
-  const PRUint32 COLOR_ARRAY_POINTER            = 0x8090;
-  const PRUint32 TEXTURE_COORD_ARRAY_POINTER    = 0x8092;
-  const PRUint32 SAMPLE_BUFFERS                 = 0x80A8;
-  const PRUint32 SAMPLES                        = 0x80A9;
-  const PRUint32 SAMPLE_COVERAGE_VALUE          = 0x80AA;
-  const PRUint32 SAMPLE_COVERAGE_INVERT         = 0x80AB;
-
-  /* GetTextureParameter */
-  /*             TEXTURE_MAG_FILTER */
-  /*             TEXTURE_MIN_FILTER */
-  /*             TEXTURE_WRAP_S */
-  /*             TEXTURE_WRAP_T */
-  
-  /* HintMode */
-  const PRUint32 DONT_CARE                      = 0x1100;
-  const PRUint32 FASTEST                        = 0x1101;
-  const PRUint32 NICEST                         = 0x1102;
-
-  /* HintTarget */
-  const PRUint32 PERSPECTIVE_CORRECTION_HINT    = 0x0C50;
-  const PRUint32 POINT_SMOOTH_HINT              = 0x0C51;
-  const PRUint32 LINE_SMOOTH_HINT               = 0x0C52;
-  const PRUint32 POLYGON_SMOOTH_HINT            = 0x0C53;
-  const PRUint32 FOG_HINT                       = 0x0C54;
-  const PRUint32 GENERATE_MIPMAP_HINT           = 0x8192;
-
-  /* LightModelParameter */
-  const PRUint32 LIGHT_MODEL_AMBIENT            = 0x0B53;
-  const PRUint32 LIGHT_MODEL_TWO_SIDE           = 0x0B52;
-  const PRUint32 LIGHT_MODEL_LOCAL_VIEWER       = 0x0B51;
-  const PRUint32 LIGHT_MODEL_COLOR_CONTROL      = 0x81F8;
-
-  /* LightParameter */
-  const PRUint32 AMBIENT                        = 0x1200;
-  const PRUint32 DIFFUSE                        = 0x1201;
-  const PRUint32 SPECULAR                       = 0x1202;
-  const PRUint32 POSITION                       = 0x1203;
-  const PRUint32 SPOT_DIRECTION                 = 0x1204;
-  const PRUint32 SPOT_EXPONENT                  = 0x1205;
-  const PRUint32 SPOT_CUTOFF                    = 0x1206;
-  const PRUint32 CONSTANT_ATTENUATION           = 0x1207;
-  const PRUint32 LINEAR_ATTENUATION             = 0x1208;
-  const PRUint32 QUADRATIC_ATTENUATION          = 0x1209;
-
-  /* LogicOp */
-  /* CLEAR -> CLEAR_OP, because clear() is a method */
-  const PRUint32 CLEAR_OP                       = 0x1500;
-  const PRUint32 AND                            = 0x1501;
-  const PRUint32 AND_REVERSE                    = 0x1502;
-  const PRUint32 COPY                           = 0x1503;
-  const PRUint32 AND_INVERTED                   = 0x1504;
-  const PRUint32 NOOP                           = 0x1505;
-  const PRUint32 XOR                            = 0x1506;
-  const PRUint32 OR                             = 0x1507;
-  const PRUint32 NOR                            = 0x1508;
-  const PRUint32 EQUIV                          = 0x1509;
-  const PRUint32 INVERT                         = 0x150A;
-  const PRUint32 OR_REVERSE                     = 0x150B;
-  const PRUint32 COPY_INVERTED                  = 0x150C;
-  const PRUint32 OR_INVERTED                    = 0x150D;
-  const PRUint32 NAND                           = 0x150E;
-  const PRUint32 SET                            = 0x150F;
-
-  /* MaterialFace */
-  /*             FRONT_AND_BACK */
-
-  /* MaterialParameter */
-  const PRUint32 EMISSION                       = 0x1600;
-  const PRUint32 SHININESS                      = 0x1601;
-  const PRUint32 AMBIENT_AND_DIFFUSE            = 0x1602;
-
-  /* MatrixMode */
-  const PRUint32 MODELVIEW                      = 0x1700;
-  const PRUint32 PROJECTION                     = 0x1701;
-  const PRUint32 TEXTURE                        = 0x1702;
-
-  /* LightName */
-  const PRUint32 LIGHT0                         = 0x4000;
-  const PRUint32 LIGHT1                         = 0x4001;
-  const PRUint32 LIGHT2                         = 0x4002;
-  const PRUint32 LIGHT3                         = 0x4003;
-  const PRUint32 LIGHT4                         = 0x4004;
-  const PRUint32 LIGHT5                         = 0x4005;
-  const PRUint32 LIGHT6                         = 0x4006;
-  const PRUint32 LIGHT7                         = 0x4007;
-
-  /* ShadingModel */
-  const PRUint32 FLAT                           = 0x1D00;
-  const PRUint32 SMOOTH                         = 0x1D01;
-
-  /* StencilFunction */
-  /*             NEVER */
-  /*             LESS */
-  /*             EQUAL */
-  /*             LEQUAL */
-  /*             GREATER */
-  /*             NOTEQUAL */
-  /*             GEQUAL */
-  /*             ALWAYS */
-
-  /* StencilOp */
-  /*             ZERO */
-  const PRUint32 KEEP                           = 0x1E00;
-  const PRUint32 REPLACE                        = 0x1E01;
-  const PRUint32 INCR                           = 0x1E02;
-  const PRUint32 DECR                           = 0x1E03;
-  /*             INVERT */
-
-  /* StringName */
-  const PRUint32 VENDOR                         = 0x1F00;
-  const PRUint32 RENDERER                       = 0x1F01;
-  const PRUint32 VERSION                        = 0x1F02;
-  const PRUint32 EXTENSIONS                     = 0x1F03;
-
-  /* TextureEnvMode */
-  const PRUint32 MODULATE                       = 0x2100;
-  const PRUint32 DECAL                          = 0x2101;
-  /*             BLEND */
-  const PRUint32 ADD                            = 0x0104;
-  //             REPLACE
-  /*             COMBINE */
-
-  /* TextureEnvParameter */
-  const PRUint32 TEXTURE_ENV_MODE               = 0x2200;
-  const PRUint32 TEXTURE_ENV_COLOR              = 0x2201;
-
-  /* TextureEnvTarget */
-  const PRUint32 TEXTURE_ENV                    = 0x2300;
-
-  /* TextureMagFilter */
-  const PRUint32 NEAREST                        = 0x2600;
-  const PRUint32 LINEAR                         = 0x2601;
-
-  /* TextureMinFilter */
-  /*             NEAREST */
-  /*             LINEAR */
-  const PRUint32 NEAREST_MIPMAP_NEAREST         = 0x2700;
-  const PRUint32 LINEAR_MIPMAP_NEAREST          = 0x2701;
-  const PRUint32 NEAREST_MIPMAP_LINEAR          = 0x2702;
-  const PRUint32 LINEAR_MIPMAP_LINEAR           = 0x2703;
-
-  /* TextureParameterName */
-  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 GENERATE_MIPMAP                = 0x8191;
-
-  /* TextureUnit */
-  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 CLIENT_ACTIVE_TEXTURE          = 0x84E1;
-
-  /* TextureWrapMode */
-  const PRUint32 REPEAT                         = 0x2901;
-  const PRUint32 CLAMP_TO_EDGE                  = 0x812F;
-
-  /* Texture combine + dot3 */
-  const PRUint32 SUBTRACT                       = 0x84E7;
-  const PRUint32 COMBINE                        = 0x8570;
-  const PRUint32 COMBINE_RGB                    = 0x8571;
-  const PRUint32 COMBINE_ALPHA                  = 0x8572;
-  const PRUint32 RGB_SCALE                      = 0x8573;
-  const PRUint32 ADD_SIGNED                     = 0x8574;
-  const PRUint32 INTERPOLATE                    = 0x8575;
-  const PRUint32 CONSTANT                       = 0x8576;
-  const PRUint32 PRIMARY_COLOR                  = 0x8577;
-  const PRUint32 PREVIOUS                       = 0x8578;
-  const PRUint32 OPERAND0_RGB                   = 0x8590;
-  const PRUint32 OPERAND1_RGB                   = 0x8591;
-  const PRUint32 OPERAND2_RGB                   = 0x8592;
-  const PRUint32 OPERAND0_ALPHA                 = 0x8598;
-  const PRUint32 OPERAND1_ALPHA                 = 0x8599;
-  const PRUint32 OPERAND2_ALPHA                 = 0x859A;
-
-  const PRUint32 ALPHA_SCALE                    = 0x0D1C;
-
-  const PRUint32 SRC0_RGB                       = 0x8580;
-  const PRUint32 SRC1_RGB                       = 0x8581;
-  const PRUint32 SRC2_RGB                       = 0x8582;
-  const PRUint32 SRC0_ALPHA                     = 0x8588;
-  const PRUint32 SRC1_ALPHA                     = 0x8589;
-  const PRUint32 SRC2_ALPHA                     = 0x858A;
-
-  const PRUint32 DOT3_RGB                       = 0x86AE;
-  const PRUint32 DOT3_RGBA                      = 0x86AF;
-
-  /* Buffers */
-  const PRUint32 STATIC_DRAW                    = 0x88E4;
-  const PRUint32 DYNAMIC_DRAW                   = 0x88E8;
-  const PRUint32 ARRAY_BUFFER                   = 0x8892;
-  const PRUint32 ELEMENT_ARRAY_BUFFER           = 0x8893;
-  const PRUint32 ARRAY_BUFFER_BINDING = 0x8894;
-  const PRUint32 ELEMENT_ARRAY_BUFFER_BINDING = 0x8895;
-
-  /* Extensions */
-  const PRUint32 TEXTURE_RECTANGLE              = 0x84F5;
-  const PRUint32 TEXTURE_BINDING_RECTANGLE      = 0x84F6;
-  const PRUint32 MAX_RECTANGLE_TEXTURE_SIZE     = 0x84F8;
-
-  const PRUint32 TEXTURE_MAX_ANISOTROPY         = 0x84FE;
-  const PRUint32 MAX_TEXTURE_MAX_ANISOTROPY     = 0x84FF;
-
-
-
   /**
    ** GL ES 1.1 API
    **
    ** Section numbers refer to the GL ES Common/Common-Lite Profile Specification 1.0 document
    **/
 
   void enable (in PRUint32 mode);
   void disable (in PRUint32 mode);
@@ -617,17 +94,17 @@ interface nsICanvasRenderingContextGLES1
 
   // JS buffer objects; will use buffer objects extension if available,
   // otherwise will just store in client memeory
 
   //void bindBufferObject (in PRUint32 target, in nsICanvasRenderingContextGLES11Buffer obj);
 
   //X nsICanvasRenderingContextGLES11Buffer
   //X   createBuffer(in PRInt32 usage, in PRInt32 componentSize, in PRInt32 type, in [] array);
-  nsICanvasRenderingContextGLES11Buffer createBuffer();
+  nsICanvasRenderingContextGLBuffer createBuffer();
 
   // 2.11 Coordinate Transformations
   void depthRange (in float zNear, in float zFar);
   void viewport (in PRInt32 x, in PRInt32 y, in PRInt32 width, in PRInt32 height);
   void matrixMode (in PRUint32 mode);
   //X void loadMatrix (in float [] matrix);
   void loadMatrix ();
   //X void multMatrix (in float [] matrix);
@@ -665,19 +142,19 @@ interface nsICanvasRenderingContextGLES1
 
   // 3.6 Pixel Rectangles
   // glReadPixels is not supported (XXX well, it might be)
   // and TexImage2D behaves differently, so no need for PixelStore[i]
 
   // 3.8.5 Texture State
   void activeTexture (in PRUint32 texture);
 
-  nsICanvasRenderingContextGLES11Texture createTextureObject (in nsIDOMHTMLElement imageOrCanvas);
-  void bindTextureObject (in nsICanvasRenderingContextGLES11Texture texture);
-  void deleteTextureObject (in nsICanvasRenderingContextGLES11Texture texture);
+  nsICanvasRenderingContextGLTexture createTextureObject (in nsIDOMHTMLElement imageOrCanvas);
+  void bindTextureObject (in nsICanvasRenderingContextGLTexture texture);
+  void deleteTextureObject (in nsICanvasRenderingContextGLTexture texture);
 
   // This needs some work; we need to allow specifying the internal format, so that
   // we can load A/L/LA images as well as RGB/RGBA, which is all we'd get from a DOM Image
   void texImage2DHTML (in PRUint32 target, in nsIDOMHTMLElement imageOrCanvas);
   //void texSubImage2DHTML (...);
 
   void texParameter();
   void getTexParameter();
@@ -726,17 +203,14 @@ interface nsICanvasRenderingContextGLES1
 
   // 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);
 
-  // Other
-  void swapBuffers ();
-
   // More other
   void gluPerspective (in float fovy, in float aspect, in float znear, in float zfar);
   void gluLookAt (in float eyex, in float eyey, in float eyez,
                   in float ctrx, in float ctry, in float ctrz,
                   in float upx, in float upy, in float upz);
 };
new file mode 100644
--- /dev/null
+++ b/extensions/canvas3d/public/nsICanvasRenderingContextGLWeb20.idl
@@ -0,0 +1,184 @@
+/* -*- 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"
+
+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);
+
+  /* array, type, usage */
+  void bufferData ();
+  /* offset, array, type */
+  void bufferSubData ();
+
+  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
+
+  // YES copyTexImage2D
+
+  PRUint32 createProgram ();
+  PRUint32 createShader (in PRUint32 type);
+  void cullFace (in PRUint32 face);
+
+  /* [array of buffers] */
+  void deleteBuffers ();
+  void deleteTextures ();
+  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 ();
+  void enable (in PRUint32 mode);
+  void enableVertexAttribArray (in PRUint32 index);
+  // NO Finish
+  // NO 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);
+  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 polygonOffset (in float factor, in float units);
+
+  // NO readPixels
+
+  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 texImage2DHTML (in PRUint32 target, in nsIDOMHTMLElement imageOrCanvas);
+
+  void texParameter();
+
+  // YES void texSubImage2DHTML (...);
+
+  // need better names for this
+  void uniformi();
+  void uniformf();
+  void uniformMatrix();
+
+  void useProgram (in PRUint32 program);
+  void validateProgram (in PRUint32 program);
+
+  void vertexAttrib ();
+  void vertexAttribPointer ();
+
+  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);
+};
\ No newline at end of file
--- a/extensions/canvas3d/src/Makefile.in
+++ b/extensions/canvas3d/src/Makefile.in
@@ -43,17 +43,17 @@ VPATH            = @srcdir@
 
 include $(DEPTH)/config/autoconf.mk
 
 MODULE		= canvas3d
 LIBRARY_NAME	= canvas3d
 
 XPI_NAME	= canvas3d
 
-EXPORT_LIBRARY	= 1
+EXPORT_LIBRARY	= 0
 IS_COMPONENT	= 1
 MODULE_NAME	= nsCanvas3DModule
 GRE_MODULE	= 1
 MOZILLA_INTERNAL_API = 1
 BUILD_STATIC_LIBS =
 
 REQUIRES	= \
 		xpcom \
@@ -144,31 +144,34 @@ ifneq (,$(filter $(MOZ_WIDGET_TOOLKIT),m
 endif
 
 CSRCS		= $(GLITZ_CSRCS) \
 		  glew.c \
 		  $(NULL)
 
 VPATH += $(topsrcdir)/gfx/src
 CPPSRCS		= nsCanvas3DModule.cpp \
+		  nsCanvasRenderingContextGL.cpp \
 		  nsCanvasRenderingContextGLES11.cpp \
+		  nsCanvasRenderingContextGLWeb20.cpp \
 		  $(NULL)
 
 DEFINES += -DXPCOM_GLUE -DGLEW_MX -DGLEW_STATIC
 
-EXTRA_DSO_LIBS += js3250 mozcairo mozlibpixman xpcom nspr4 xpcom_core
+EXTRA_DSO_LIBS += js3250 xpcom nspr4 xpcom_core unicharutil_s
+# mozcairo mozlibpixman
 
 ifdef MOZ_ENABLE_CAIRO_GFX
-EXTRA_DSO_LIBS += thebes
+EXTRA_DSO_LDOPTS += $(DEPTH)/gfx/thebes/src/thebes.lib $(DEPTH)/gfx/src/gkgfx.lib
 endif
 
 # Hack for getting an extension built against static vs. dynamic versions of firefox
-ifeq (,$(BUILD_STATIC_LIBS))
-EXTRA_DSO_LIBS += gkgfx
-endif
+##ifeq (,$(BUILD_STATIC_LIBS))
+#EXTRA_DSO_LIBS += gkgfx
+#endif
 
 include $(topsrcdir)/config/rules.mk
 
 CFLAGS += -I$(GLITZ_SRC_DIR) -I$(GLITZ_PLATFORM_SRC_DIR) $(RTL_FLAGS)
 CXXFLAGS += -I$(GLITZ_SRC_DIR) -I$(GLITZ_PLATFORM_SRC_DIR) $(MOZ_CAIRO_CFLAGS) $(TK_CFLAGS)
 
 ifdef MOZ_X11
 endif
--- a/extensions/canvas3d/src/nsCanvas3DModule.cpp
+++ b/extensions/canvas3d/src/nsCanvas3DModule.cpp
@@ -41,23 +41,30 @@
 #include "nsIComponentManager.h"
 #include "nsIGenericFactory.h"
 
 #ifndef MOZILLA_1_8_BRANCH
 #include "nsIClassInfoImpl.h"
 #endif
 
 #include "nsICanvasRenderingContextGLES11.h"
+#include "nsICanvasRenderingContextGLWeb20.h"
 
 // {21788585-e91c-448c-8bb9-6c51aba9735f}
 #define NS_CANVASRENDERINGCONTEXTGLES11_CID \
 { 0x21788585, 0xe91c, 0x448c, { 0x8b, 0xb9, 0x6c, 0x51, 0xab, 0xa9, 0x73, 0x5f } }
 
+// {8CB888F5-D754-4e5b-8C72-A5CC798CBB8F}
+#define NS_CANVASRENDERINGCONTEXTGLWEB20_CID \
+{ 0x8cb888f5, 0xd754, 0x4e5b, { 0x8c, 0x72, 0xa5, 0xcc, 0x79, 0x8c, 0xbb, 0x8f } }
+
 nsresult NS_NewCanvasRenderingContextGLES11(nsICanvasRenderingContextGLES11** aResult);
 
+nsresult NS_NewCanvasRenderingContextGLWeb20(nsICanvasRenderingContextGLWeb20** aResult);
+
 #define MAKE_CTOR(ctor_, iface_, func_)                   \
 static NS_IMETHODIMP                                      \
 ctor_(nsISupports* aOuter, REFNSIID aIID, void** aResult) \
 {                                                         \
   *aResult = nsnull;                                      \
   if (aOuter)                                             \
     return NS_ERROR_NO_AGGREGATION;                       \
   iface_* inst;                                           \
@@ -65,25 +72,36 @@ ctor_(nsISupports* aOuter, REFNSIID aIID
   if (NS_SUCCEEDED(rv)) {                                 \
     rv = inst->QueryInterface(aIID, aResult);             \
     NS_RELEASE(inst);                                     \
   }                                                       \
   return rv;                                              \
 }
 
 NS_DECL_CLASSINFO(nsCanvasRenderingContextGLES11)
+MAKE_CTOR(CreateCanvasRenderingContextGLES11, nsICanvasRenderingContextGLES11, NS_NewCanvasRenderingContextGLES11)
 
-MAKE_CTOR(CreateCanvasRenderingContextGLES11, nsICanvasRenderingContextGLES11, NS_NewCanvasRenderingContextGLES11)
+NS_DECL_CLASSINFO(nsCanvasRenderingContextGLWeb20)
+MAKE_CTOR(CreateCanvasRenderingContextGLWeb20, nsICanvasRenderingContextGLWeb20, NS_NewCanvasRenderingContextGLWeb20)
 
 static const nsModuleComponentInfo components[] = {
     { "GLES 1.1 Canvas Context",
       NS_CANVASRENDERINGCONTEXTGLES11_CID,
-      "@mozilla.org/content/canvas-rendering-context;1?id=gles11",
+      "@mozilla.org/content/canvas-rendering-context;1?id=moz-gles11",
       CreateCanvasRenderingContextGLES11,
       nsnull, nsnull, nsnull,
       NS_CI_INTERFACE_GETTER_NAME(nsCanvasRenderingContextGLES11),
       nsnull, &NS_CLASSINFO_NAME(nsCanvasRenderingContextGLES11),
       nsIClassInfo::DOM_OBJECT
     },
+    { "GLES 2.0 Canvas Context",
+      NS_CANVASRENDERINGCONTEXTGLWEB20_CID,
+      "@mozilla.org/content/canvas-rendering-context;1?id=moz-glweb20",
+      CreateCanvasRenderingContextGLWeb20,
+      nsnull, nsnull, nsnull,
+      NS_CI_INTERFACE_GETTER_NAME(nsCanvasRenderingContextGLWeb20),
+      nsnull, &NS_CLASSINFO_NAME(nsCanvasRenderingContextGLWeb20),
+      nsIClassInfo::DOM_OBJECT
+    },
 };
 
 NS_IMPL_NSGETMODULE(nsCanvas3DModule, components)
 
new file mode 100644
--- /dev/null
+++ b/extensions/canvas3d/src/nsCanvasRenderingContextGL.cpp
@@ -0,0 +1,1548 @@
+/* -*- 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 "prmem.h"
+#include "prlog.h"
+
+#include "nsCanvasRenderingContextGL.h"
+
+#include "nsIRenderingContext.h"
+
+#include "nsICanvasRenderingContextInternal.h"
+#include "nsIDOMHTMLCanvasElement.h"
+#include "nsIView.h"
+#include "nsIViewManager.h"
+
+#ifndef MOZILLA_1_8_BRANCH
+#include "nsIDocument.h"
+#endif
+
+#include "nsTransform2D.h"
+
+#include "nsIScriptSecurityManager.h"
+#include "nsISecurityCheckedComponent.h"
+
+#include "imgIRequest.h"
+#include "imgIContainer.h"
+#include "gfxIImageFrame.h"
+#include "nsIDOMHTMLCanvasElement.h"
+#include "nsICanvasElement.h"
+#include "nsIDOMHTMLImageElement.h"
+#include "nsIImageLoadingContent.h"
+#include "nsIInterfaceRequestorUtils.h"
+#include "nsIImage.h"
+#include "nsIFrame.h"
+#include "nsDOMError.h"
+#include "nsIJSRuntimeService.h"
+
+#ifndef MOZILLA_1_8_BRANCH
+#include "nsIClassInfoImpl.h"
+#endif
+
+#include "nsServiceManagerUtils.h"
+
+#include "nsDOMError.h"
+
+#include "nsContentUtils.h"
+
+#include "nsIXPConnect.h"
+#include "jsapi.h"
+
+// GLEW will pull in the GL bits that we want/need
+#include "glew.h"
+
+// we're hoping that something is setting us up the remap
+
+#include "cairo.h"
+#include "glitz.h"
+
+#ifdef MOZ_CAIRO_GFX
+#include "gfxContext.h"
+#include "gfxASurface.h"
+#endif
+
+#ifdef XP_WIN
+#include "cairo-win32.h"
+#include "glitz-wgl.h"
+
+#ifdef MOZILLA_1_8_BRANCH
+struct _cairo_surface_win32_hack {
+    void *ptr;
+    unsigned int refcnt;
+    cairo_status_t st;
+    cairo_bool_t finished;
+    /* array_t */
+    int sz;
+    int num_el;
+    int el_sz;
+    void *elements;
+    double dx, dy, dxs, dys;
+    unsigned int a;
+    unsigned int b;
+
+    /* win32 */
+    cairo_format_t format;
+};
+#endif
+#endif
+
+#ifdef MOZ_X11
+#include <gdk/gdk.h>
+#include <gdk/gdkx.h>
+#include "cairo-xlib.h"
+#include "glitz-glx.h"
+#endif
+
+nsIXPConnect *gXPConnect = nsnull;
+JSRuntime *gScriptRuntime = nsnull;
+nsIJSRuntimeService *gJSRuntimeService = nsnull;
+PRBool gGlitzInitialized = PR_FALSE;
+
+// CanvasGLBuffer
+NS_DECL_CLASSINFO(CanvasGLBuffer)
+NS_IMPL_ADDREF(CanvasGLBuffer)
+NS_IMPL_RELEASE(CanvasGLBuffer)
+
+NS_IMPL_CI_INTERFACE_GETTER1(CanvasGLBuffer, nsICanvasRenderingContextGLBuffer)
+
+NS_INTERFACE_MAP_BEGIN(CanvasGLBuffer)
+  NS_INTERFACE_MAP_ENTRY(nsICanvasRenderingContextGLBuffer)
+  NS_INTERFACE_MAP_ENTRY(nsISecurityCheckedComponent)
+  NS_INTERFACE_MAP_ENTRY(nsICanvasGLBuffer)
+  NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsICanvasRenderingContextGLBuffer)
+  NS_IMPL_QUERY_CLASSINFO(CanvasGLBuffer)
+NS_INTERFACE_MAP_END
+
+// CanvasGLTexture
+NS_DECL_CLASSINFO(CanvasGLTexture)
+NS_IMPL_ADDREF(CanvasGLTexture)
+NS_IMPL_RELEASE(CanvasGLTexture)
+
+NS_IMPL_CI_INTERFACE_GETTER1(CanvasGLTexture, nsICanvasRenderingContextGLTexture)
+
+NS_INTERFACE_MAP_BEGIN(CanvasGLTexture)
+  NS_INTERFACE_MAP_ENTRY(nsICanvasRenderingContextGLTexture)
+  NS_INTERFACE_MAP_ENTRY(nsICanvasGLTexture)
+  NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsICanvasRenderingContextGLTexture)
+  NS_IMPL_QUERY_CLASSINFO(CanvasGLTexture)
+NS_INTERFACE_MAP_END
+
+/**
+ ** CanvasGLBuffer
+ **/
+
+static int bufferCount = 0;
+
+CanvasGLBuffer::CanvasGLBuffer(nsCanvasRenderingContextGLPrivate *owner)
+    : mDisposed(PR_TRUE),
+      mLength(0), mSize(0), mType(0), mUsage(GL_STATIC_DRAW),
+      mBufferID(0)
+{
+    owner->GetWeakReference(getter_AddRefs(mOwnerContext));
+
+    bufferCount++;
+    fprintf (stderr, "VVVV Created; Buffers now: %d\n", bufferCount); fflush(stderr);
+}
+
+CanvasGLBuffer::~CanvasGLBuffer()
+{
+    Dispose();
+
+    --bufferCount;
+    fprintf (stderr, "VVVV Released; Buffers now: %d\n", bufferCount); fflush(stderr);
+}
+
+/* nsISecurityCheckedComponent bits */
+
+static char* cloneAllAccess()
+{
+    static const char allAccess[] = "allAccess";
+    return (char*)nsMemory::Clone(allAccess, sizeof(allAccess));
+}
+
+NS_IMETHODIMP
+CanvasGLBuffer::CanCreateWrapper(const nsIID* iid, char **_retval) {
+    *_retval = cloneAllAccess();
+    return NS_OK;
+}
+
+NS_IMETHODIMP
+CanvasGLBuffer::CanCallMethod(const nsIID *iid, const PRUnichar *methodName, char **_retval) {
+    *_retval = cloneAllAccess();
+    return NS_OK;
+}
+
+NS_IMETHODIMP
+CanvasGLBuffer::CanGetProperty(const nsIID *iid, const PRUnichar *propertyName, char **_retval) {
+    *_retval = cloneAllAccess();
+    return NS_OK;
+}
+
+NS_IMETHODIMP
+CanvasGLBuffer::CanSetProperty(const nsIID *iid, const PRUnichar *propertyName, char **_retval) {
+    *_retval = cloneAllAccess();
+    return NS_OK;
+}
+
+nsresult
+CanvasGLBuffer::Init(PRUint32 usage,
+                     PRUint32 size,
+                     PRUint32 type,
+                     JSContext *ctx,
+                     JSObject *arrayObj,
+                     jsuint arrayLen)
+{
+    nsresult rv;
+
+    fprintf (stderr, "VVVV CanvasGLBuffer::Init\n");
+
+    if (!mDisposed)
+        Dispose();
+
+    if (usage != GL_STATIC_DRAW &&
+        usage != GL_DYNAMIC_DRAW)
+        return NS_ERROR_INVALID_ARG;
+
+    rv = JSArrayToSimpleBuffer(mSimpleBuffer, type, size, ctx, arrayObj, arrayLen);
+    if (NS_FAILED(rv))
+        return rv;
+
+    mUsage = usage;
+    mSize = size;
+    mType = type;
+    mLength = arrayLen;
+
+    mBufferID = 0;
+
+    mDisposed = PR_FALSE;
+
+    return NS_OK;
+}
+
+NS_IMETHODIMP
+CanvasGLBuffer::Dispose()
+{
+    if (mDisposed)
+        return NS_OK;
+
+    if (mBufferID) {
+        nsCOMPtr<nsICanvasRenderingContextInternal> ctx = do_QueryReferent(mOwnerContext);
+        if (ctx) {
+            nsCanvasRenderingContextGLPrivate *priv = (nsCanvasRenderingContextGLPrivate*) ctx.get();
+            mGlewContextPtr = priv->glewGetContext();
+            priv->MakeContextCurrent();
+
+            glDeleteBuffers(1, &mBufferID);
+            mBufferID = 0;
+        }
+    }
+
+    mSimpleBuffer.Release();
+
+    mDisposed = PR_TRUE;
+    return NS_OK;
+}
+
+NS_IMETHODIMP
+CanvasGLBuffer::GetOwnerContext(nsICanvasRenderingContextGL **retval)
+{
+    nsCOMPtr<nsICanvasRenderingContextInternal> ctx = do_QueryReferent(mOwnerContext);
+    if (ctx) {
+        nsCanvasRenderingContextGLPrivate *priv = (nsCanvasRenderingContextGLPrivate*) ctx.get();
+        *retval = priv->GetSelf();
+    } else {
+        *retval = nsnull;
+    }
+
+    NS_IF_ADDREF(*retval);
+    return NS_OK;
+}
+
+NS_IMETHODIMP
+CanvasGLBuffer::GetDisposed(PRBool *retval)
+{
+    *retval = mDisposed;
+    return NS_OK;
+}
+
+NS_IMETHODIMP
+CanvasGLBuffer::GetUsage(PRUint32 *usage)
+{
+    if (mDisposed)
+        return NS_ERROR_FAILURE;
+
+    *usage = mUsage;
+    return NS_OK;
+}
+
+NS_IMETHODIMP
+CanvasGLBuffer::GetLength(PRUint32 *retval)
+{
+    if (mDisposed)
+        return NS_ERROR_FAILURE;
+
+    *retval = mLength;
+    return NS_OK;
+}
+
+NS_IMETHODIMP
+CanvasGLBuffer::GetType(PRUint32 *retval)
+{
+    if (mDisposed)
+        return NS_ERROR_FAILURE;
+
+    *retval = mType;
+    return NS_OK;
+}
+
+/**
+ ** CanvasGLTexture
+ **/
+
+CanvasGLTexture::CanvasGLTexture(nsCanvasRenderingContextGLPrivate *owner)
+    : mDisposed(PR_FALSE),
+      mGlitzTextureSurface(nsnull), mGlitzTextureObject(nsnull),
+      mWidth(0), mHeight(0)
+{
+    owner->GetWeakReference(getter_AddRefs(mOwnerContext));
+}
+
+CanvasGLTexture::~CanvasGLTexture()
+{
+    Dispose();
+}
+
+nsresult
+CanvasGLTexture::Init()
+{
+    return NS_OK;
+}
+
+nsresult
+CanvasGLTexture::Dispose()
+{
+    if (mDisposed)
+        return NS_OK;
+
+    mDisposed = PR_TRUE;
+    return NS_OK;
+}
+
+NS_IMETHODIMP
+CanvasGLTexture::GetDisposed(PRBool *retval)
+{
+    *retval = mDisposed;
+    return NS_OK;
+}
+
+NS_IMETHODIMP
+CanvasGLTexture::GetOwnerContext(nsICanvasRenderingContextGL **retval)
+{
+    nsCOMPtr<nsICanvasRenderingContextInternal> ctx = do_QueryReferent(mOwnerContext);
+    if (ctx) {
+        nsCanvasRenderingContextGLPrivate *priv = (nsCanvasRenderingContextGLPrivate*) ctx.get();
+        *retval = priv->GetSelf();
+    } else {
+        *retval = nsnull;
+    }
+
+    NS_IF_ADDREF(*retval);
+    return NS_OK;
+}
+
+NS_IMETHODIMP
+CanvasGLTexture::GetTarget(PRUint32 *aResult)
+{
+    *aResult = glitz_texture_object_get_target (mGlitzTextureObject);
+    return NS_OK;
+}
+
+NS_IMETHODIMP
+CanvasGLTexture::GetWidth(PRUint32 *aWidth)
+{
+    *aWidth = mWidth;
+    return NS_OK;
+}
+
+NS_IMETHODIMP
+CanvasGLTexture::GetHeight(PRUint32 *aHeight)
+{
+    *aHeight = mHeight;
+    return NS_OK;
+}
+
+NS_IMETHODIMP
+CanvasGLTexture::SetFilter(PRUint32 filterType, PRUint32 filterMode)
+{
+    if (filterType < 0 || filterType > 1 ||
+        filterMode < 0 || filterMode > 1)
+    {
+        return NS_ERROR_DOM_SYNTAX_ERR;
+    }
+
+    glitz_texture_object_set_filter (mGlitzTextureObject, (glitz_texture_filter_type_t)filterType, (glitz_texture_filter_t)filterMode);
+    return NS_OK;
+}
+
+NS_IMETHODIMP
+CanvasGLTexture::SetWrap(PRUint32 wrapType, PRUint32 wrapMode)
+{
+    if (wrapType != GLITZ_TEXTURE_WRAP_TYPE_S &&
+        wrapType != GLITZ_TEXTURE_WRAP_TYPE_T)
+        return NS_ERROR_DOM_SYNTAX_ERR;
+
+    if (wrapMode != GLITZ_TEXTURE_WRAP_CLAMP_TO_EDGE &&
+        wrapMode != GLITZ_TEXTURE_WRAP_REPEAT &&
+        wrapMode != GLITZ_TEXTURE_WRAP_MIRRORED_REPEAT)
+        return NS_ERROR_DOM_SYNTAX_ERR;
+
+    glitz_texture_object_set_wrap (mGlitzTextureObject, (glitz_texture_wrap_type_t)wrapType, (glitz_texture_wrap_t)wrapMode);
+    return NS_OK;
+}
+
+nsresult
+JSArrayToSimpleBuffer (SimpleBuffer& sbuffer,
+                       PRUint32 typeParam,
+                       PRUint32 sizeParam,
+                       JSContext *ctx,
+                       JSObject *arrayObj,
+                       jsuint arrayLen)
+{
+    sbuffer.Prepare(typeParam, sizeParam, arrayLen);
+
+    if (typeParam == GL_SHORT) {
+        short *ptr = (short*) sbuffer.data;
+        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 == GL_FLOAT) {
+        float *ptr = (float*) sbuffer.data;
+        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;
+        }
+    } else if (typeParam == GL_UNSIGNED_BYTE) {
+        unsigned char *ptr = (unsigned char*) sbuffer.data;
+        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 == GL_UNSIGNED_INT) {
+        PRUint32 *ptr = (PRUint32*) sbuffer.data;
+        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 {
+        return NS_ERROR_NOT_IMPLEMENTED;
+    }
+
+    return NS_OK;
+}
+
+void
+nsCanvasRenderingContextGLPrivate::MakeContextCurrent()
+{
+#ifdef XP_WIN
+    if (mContextToken == nsnull) {
+        glitz_context_make_current (mGlitzContext, mGlitzDrawable);
+        mContextToken = wglGetCurrentContext();
+        mCurrent = PR_TRUE;
+        return;
+    }
+
+    if (mContextToken != wglGetCurrentContext()) {
+        glitz_context_make_current (mGlitzContext, mGlitzDrawable);
+        mCurrent = PR_TRUE;
+    }
+#endif
+
+#if 0
+    if (!mCurrent) {
+        fprintf (stderr, "[this:%p] Making context %p current (current: %d)\n", this, mGlitzContext, mCurrent);
+        fflush (stderr);
+        glitz_context_set_user_data (mGlitzContext, this, LostCurrentContext);
+    }
+#endif
+}
+
+void
+nsCanvasRenderingContextGLPrivate::LostCurrentContext(void *closure)
+{
+    nsCanvasRenderingContextGLPrivate* self = (nsCanvasRenderingContextGLPrivate*) closure;
+    fprintf (stderr, "[this:%p] Lost context\n", closure);
+    fflush (stderr);
+
+    self->mCurrent = PR_FALSE;
+}
+
+//
+// nsICanvasRenderingContextInternal
+//
+
+NS_IMETHODIMP
+nsCanvasRenderingContextGLPrivate::SetCanvasElement(nsICanvasElement* aParentCanvas)
+{
+    if (!SafeToCreateCanvas3DContext())
+        return NS_ERROR_FAILURE;
+
+    if (!ValidateGL())
+        return NS_ERROR_FAILURE;
+
+    mCanvasElement = aParentCanvas;
+    fprintf (stderr, "VVVV SetCanvasElement: %p\n", mCanvasElement);
+    return NS_OK;
+}
+
+NS_IMETHODIMP
+nsCanvasRenderingContextGLPrivate::SetDimensions(PRInt32 width, PRInt32 height)
+{
+    if (mWidth == width && mHeight == height)
+        return NS_OK;
+
+    Destroy();
+
+    glitz_drawable_format_t *gdformat = nsnull;
+
+#ifdef MOZ_X11
+    Display* display = GDK_DISPLAY();
+
+    glitz_drawable_format_t templ;
+    templ.color.fourcc = GLITZ_FOURCC_RGB;
+    templ.color.red_size = 8;
+    templ.color.green_size = 8;
+    templ.color.blue_size = 8;
+    templ.color.alpha_size = 8;
+    templ.doublebuffer = 0;
+    
+    gdformat = glitz_glx_find_pbuffer_format
+        (display,
+         gdk_x11_get_default_screen(),
+         GLITZ_FORMAT_FOURCC_MASK |
+         GLITZ_FORMAT_RED_SIZE_MASK | GLITZ_FORMAT_GREEN_SIZE_MASK |
+         GLITZ_FORMAT_BLUE_SIZE_MASK | GLITZ_FORMAT_ALPHA_SIZE_MASK |
+         GLITZ_FORMAT_DOUBLEBUFFER_MASK, &templ, 0);
+
+    if (!gdformat)
+        return NS_ERROR_INVALID_ARG;
+
+    mGlitzDrawable =
+        glitz_glx_create_pbuffer_drawable(display,
+                                          DefaultScreen(display),
+                                          gdformat,
+                                          width,
+                                          height);
+#endif
+
+#ifdef XP_WIN
+    glitz_drawable_format_t templ;
+    templ.color.fourcc = GLITZ_FOURCC_RGB;
+    templ.color.red_size = 8;
+    templ.color.green_size = 8;
+    templ.color.blue_size = 8;
+    templ.color.alpha_size = 8;
+    templ.doublebuffer = 0;
+    templ.samples = 8;
+
+    gdformat = nsnull;
+
+    do {
+        templ.samples = templ.samples >> 1;
+        gdformat = glitz_wgl_find_pbuffer_format
+            (GLITZ_FORMAT_FOURCC_MASK |
+             GLITZ_FORMAT_RED_SIZE_MASK | GLITZ_FORMAT_GREEN_SIZE_MASK |
+             GLITZ_FORMAT_BLUE_SIZE_MASK | GLITZ_FORMAT_ALPHA_SIZE_MASK |
+             GLITZ_FORMAT_DOUBLEBUFFER_MASK | GLITZ_FORMAT_SAMPLES_MASK,
+             &templ, 0);
+    } while (gdformat == nsnull && templ.samples > 0);
+
+    if (!gdformat)
+        return NS_ERROR_INVALID_ARG;
+
+    mGlitzDrawable =
+        glitz_wgl_create_pbuffer_drawable(gdformat,
+                                          width,
+                                          height);
+#endif
+
+    if (!gdformat || !mGlitzDrawable)
+        return NS_ERROR_FAILURE;
+
+    glitz_format_t *gformat =
+        glitz_find_standard_format(mGlitzDrawable, GLITZ_STANDARD_ARGB32);
+    if (!gformat)
+        return NS_ERROR_INVALID_ARG;
+
+    mGlitzSurface =
+        glitz_surface_create(mGlitzDrawable,
+                             gformat,
+                             width,
+                             height,
+                             0,
+                             NULL);
+    if (!mGlitzSurface)
+        return NS_ERROR_INVALID_ARG;
+
+    glitz_surface_attach(mGlitzSurface, mGlitzDrawable, GLITZ_DRAWABLE_BUFFER_FRONT_COLOR);
+
+    mGlitzContext = glitz_context_create (mGlitzDrawable, gdformat);
+
+    MakeContextCurrent();
+
+    GLenum err = glewInit();
+    if (err != GLEW_OK) {
+        // er, something very bad happened
+        NS_ERROR("glewInit failed!  Leaking lots of memory");
+        return NS_ERROR_FAILURE;
+    }
+
+    //mSurface = new gfxGlitzSurface (mGlitzDrawable, gsurf, PR_TRUE);
+    mWidth = width;
+    mHeight = height;
+
+    mStride = (((mWidth*4) + 3) / 4) * 4;
+
+#ifdef XP_WIN
+    BITMAPINFO *bitmap_info = (BITMAPINFO*) PR_Malloc(sizeof(BITMAPINFOHEADER));
+    bitmap_info->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
+    bitmap_info->bmiHeader.biWidth = mWidth;
+    bitmap_info->bmiHeader.biHeight = mHeight;
+    bitmap_info->bmiHeader.biSizeImage = 0;
+    bitmap_info->bmiHeader.biXPelsPerMeter = 2834; /* unused here */
+    bitmap_info->bmiHeader.biYPelsPerMeter = 2834; /* unused here */
+    bitmap_info->bmiHeader.biPlanes = 1;
+    bitmap_info->bmiHeader.biBitCount = 32;
+    bitmap_info->bmiHeader.biCompression = BI_RGB;
+    bitmap_info->bmiHeader.biClrUsed = 0;	/* unused */
+    bitmap_info->bmiHeader.biClrImportant = 0;
+
+    mWinBitmapDC = CreateCompatibleDC(NULL);
+    if (mWinBitmapDC) {
+        void *bits = nsnull;
+        mWinBitmap = CreateDIBSection (mWinBitmapDC,
+                                       bitmap_info,
+                                       DIB_RGB_COLORS,
+                                       &bits,
+                                       NULL, 0);
+        if (mWinBitmap) {
+            SelectObject (mWinBitmapDC, mWinBitmap);
+            GdiFlush();
+
+            mImageBuffer = (PRUint8*) bits;
+            mCairoImageSurface = cairo_win32_surface_create (mWinBitmapDC);
+#ifdef MOZILLA_1_8_BRANCH
+            ((struct _cairo_surface_win32_hack*)mCairoImageSurface)->format = CAIRO_FORMAT_ARGB32;
+#endif
+        } else {
+            DeleteDC(mWinBitmapDC);
+        }
+    }
+
+    PR_Free(bitmap_info);
+#endif
+
+    if (!mImageBuffer) {
+        mImageBuffer = (PRUint8*) PR_Malloc(mStride * mHeight);
+        if (mImageBuffer) {
+            mCairoImageSurface = cairo_image_surface_create_for_data (mImageBuffer,
+                                                                      CAIRO_FORMAT_ARGB32,
+                                                                      mWidth,
+                                                                      mHeight,
+                                                                      mStride);
+        }
+    }
+
+    if (!mImageBuffer)
+        return NS_ERROR_FAILURE;
+
+    mGlitzImageBuffer = glitz_buffer_create_for_data (mImageBuffer);
+
+    return NS_OK;
+}
+
+/*
+ * This is identical to nsCanvasRenderingContext2D::Render, we just don't
+ * have a good place to put it; though maybe I want a CanvasContextImpl that
+ * all this stuff can derive from?
+ */
+NS_IMETHODIMP
+nsCanvasRenderingContextGLPrivate::Render(nsIRenderingContext *rc)
+{
+    nsresult rv = NS_OK;
+
+    if (!mImageBuffer)
+        return NS_OK;
+
+#ifdef MOZ_CAIRO_GFX
+
+    gfxContext* ctx = (gfxContext*) rc->GetNativeGraphicData(nsIRenderingContext::NATIVE_THEBES_CONTEXT);
+    nsRefPtr<gfxASurface> surf = gfxASurface::Wrap(mCairoImageSurface);
+    nsRefPtr<gfxPattern> pat = new gfxPattern(surf);
+
+    // XXX I don't want to use PixelSnapped here, but layout doesn't guarantee
+    // pixel alignment for this stuff!
+    ctx->NewPath();
+    ctx->PixelSnappedRectangleAndSetPattern(gfxRect(0, 0, mWidth, mHeight), pat);
+    ctx->Fill();
+
+#else
+
+    // non-Thebes; this becomes exciting
+    cairo_surface_t *dest = nsnull;
+    cairo_t *dest_cr = nsnull;
+
+#ifdef XP_WIN
+    void *ptr = nsnull;
+#ifdef MOZILLA_1_8_BRANCH
+    rv = rc->RetrieveCurrentNativeGraphicData(&ptr);
+    if (NS_FAILED(rv) || !ptr)
+        return NS_ERROR_FAILURE;
+#else
+    ptr = rc->GetNativeGraphicData(nsIRenderingContext::NATIVE_WINDOWS_DC);
+#endif
+    HDC dc = (HDC) ptr;
+
+    dest = cairo_win32_surface_create (dc);
+    dest_cr = cairo_create (dest);
+#endif
+
+#ifdef MOZ_WIDGET_GTK2
+    GdkDrawable *gdkdraw = nsnull;
+#ifdef MOZILLA_1_8_BRANCH
+    rv = rc->RetrieveCurrentNativeGraphicData((void**) &gdkdraw);
+    if (NS_FAILED(rv) || !gdkdraw)
+        return NS_ERROR_FAILURE;
+#else
+    gdkdraw = (GdkDrawable*) rc->GetNativeGraphicData(nsIRenderingContext::NATIVE_GDK_DRAWABLE);
+    if (!gdkdraw)
+        return NS_ERROR_FAILURE;
+#endif
+
+    gint w, h;
+    gdk_drawable_get_size (gdkdraw, &w, &h);
+    dest = cairo_xlib_surface_create (GDK_DRAWABLE_XDISPLAY(gdkdraw),
+                                      GDK_DRAWABLE_XID(gdkdraw),
+                                      GDK_VISUAL_XVISUAL(gdk_drawable_get_visual(gdkdraw)),
+                                      w, h);
+    dest_cr = cairo_create (dest);
+#endif
+
+    nsTransform2D *tx = nsnull;
+    rc->GetCurrentTransform(tx);
+
+    nsCOMPtr<nsIDeviceContext> dctx;
+    rc->GetDeviceContext(*getter_AddRefs(dctx));
+
+    // Until we can use the quartz2 surface, mac will be different,
+    // since we'll use CG to render.
+#ifndef XP_MACOSX
+
+    float x0 = 0.0, y0 = 0.0;
+    float sx = 1.0, sy = 1.0;
+    if (tx->GetType() & MG_2DTRANSLATION) {
+        tx->Transform(&x0, &y0);
+    }
+
+    if (tx->GetType() & MG_2DSCALE) {
+        sx = sy = dctx->DevUnitsToTwips();
+        tx->TransformNoXLate(&sx, &sy);
+    }
+
+    cairo_translate (dest_cr, NSToIntRound(x0), NSToIntRound(y0));
+    if (sx != 1.0 || sy != 1.0)
+        cairo_scale (dest_cr, sx, sy);
+
+    cairo_rectangle (dest_cr, 0, 0, mWidth, mHeight);
+    cairo_clip (dest_cr);
+
+    cairo_set_source_surface (dest_cr, mCairoImageSurface, 0, 0);
+    cairo_paint (dest_cr);
+
+    if (dest_cr)
+        cairo_destroy (dest_cr);
+    if (dest)
+        cairo_surface_destroy (dest);
+
+#else
+
+    // OSX path
+
+    CGrafPtr port = nsnull;
+#ifdef MOZILLA_1_8_BRANCH
+    rv = rc->RetrieveCurrentNativeGraphicData((void**) &port);
+    if (NS_FAILED(rv) || !port)
+        return NS_ERROR_FAILURE;
+#else
+    port = (CGrafPtr) rc->GetNativeGraphicData(nsIRenderingContext::NATIVE_MAC_THING);
+    if (!port)
+        return NS_ERROR_FAILURE;
+#endif
+
+    struct Rect portRect;
+    GetPortBounds(port, &portRect);
+
+    CGContextRef cgc;
+    OSStatus status;
+    status = QDBeginCGContext (port, &cgc);
+    if (status != noErr)
+        return NS_ERROR_FAILURE;
+
+    CGDataProviderRef dataProvider;
+    CGImageRef img;
+
+    dataProvider = CGDataProviderCreateWithData (NULL, mImageBuffer,
+                                                 mWidth * mHeight * 4,
+                                                 NULL);
+    CGColorSpaceRef rgb = CGColorSpaceCreateDeviceRGB();
+    img = CGImageCreate (mWidth, mHeight, 8, 32, mWidth * 4, rgb,
+                         kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Host,
+                         dataProvider, NULL, false, kCGRenderingIntentDefault);
+    CGColorSpaceRelease (rgb);
+    CGDataProviderRelease (dataProvider);
+
+    float x0 = 0.0, y0 = 0.0;
+    float sx = 1.0, sy = 1.0;
+    if (tx->GetType() & MG_2DTRANSLATION) {
+        tx->Transform(&x0, &y0);
+    }
+
+    if (tx->GetType() & MG_2DSCALE) {
+        float p2t = dctx->DevUnitsToTwips();
+        sx = p2t, sy = p2t;
+        tx->TransformNoXLate(&sx, &sy);
+    }
+
+    /* Compensate for the bottom-left Y origin */
+    CGContextTranslateCTM (cgc, NSToIntRound(x0),
+                           portRect.bottom - portRect.top - NSToIntRound(y0) - NSToIntRound(mHeight * sy));
+    if (sx != 1.0 || sy != 1.0)
+        CGContextScaleCTM (cgc, sx, sy);
+
+    CGContextDrawImage (cgc, CGRectMake(0, 0, mWidth, mHeight), img);
+
+    CGImageRelease (img);
+
+    status = QDEndCGContext (port, &cgc);
+    /* if EndCGContext fails, what can we do? */
+#endif
+#endif
+
+    return rv;
+}
+
+NS_IMETHODIMP
+nsCanvasRenderingContextGLPrivate::RenderToSurface(cairo_surface_t *surf)
+{
+    return NS_OK;
+}
+
+nsIFrame*
+nsCanvasRenderingContextGLPrivate::GetCanvasLayoutFrame()
+{
+    if (!mCanvasElement)
+        return nsnull;
+
+    nsIFrame *fr = nsnull;
+    mCanvasElement->GetPrimaryCanvasFrame(&fr);
+    return fr;
+}
+
+NS_IMETHODIMP
+nsCanvasRenderingContextGLPrivate::GetInputStream(const nsACString& aMimeType,
+                                                  const nsAString& aEncoderOptions,
+                                                  nsIInputStream **aStream)
+{
+    return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+void
+nsCanvasRenderingContextGLPrivate::Destroy()
+{
+    if (mCairoImageSurface) {
+        cairo_surface_destroy (mCairoImageSurface);
+        mCairoImageSurface = nsnull;
+    }
+
+    if (mGlitzImageBuffer) {
+        glitz_buffer_destroy(mGlitzImageBuffer);
+        mGlitzImageBuffer = nsnull;
+    }
+
+    if (mGlitzContext) {
+        glitz_context_destroy (mGlitzContext);
+        mGlitzContext = nsnull;
+    }
+    if (mGlitzSurface) {
+        glitz_surface_destroy (mGlitzSurface);
+        mGlitzSurface = nsnull;
+    }
+
+    // XXX bad memlk; but we already destroyed the context,
+    // so when this tries to free the fragment shaders,
+    // it tries to activate the context, and that blows up. wtf?!
+    if (mGlitzDrawable) {
+        glitz_drawable_destroy (mGlitzDrawable);
+        mGlitzDrawable = nsnull;
+    }
+
+#ifdef XP_WIN
+    if (mWinBitmapDC) {
+        DeleteDC(mWinBitmapDC);
+        mWinBitmapDC = nsnull;
+    }
+
+    if (mWinBitmap) {
+        DeleteObject(mWinBitmap);
+        mWinBitmap = nsnull;
+        mImageBuffer = nsnull;
+    }
+#endif
+
+    if (mImageBuffer) {
+        PR_Free(mImageBuffer);
+        mImageBuffer = nsnull;
+    }
+}
+
+
+/**
+ ** Helpers that really should be in some sort of cross-context shared library
+ **/
+
+nsresult
+nsCanvasRenderingContextGLPrivate::CairoSurfaceFromElement(nsIDOMElement *imgElt,
+                                                           cairo_surface_t **aCairoSurface,
+                                                           PRUint8 **imgData,
+                                                           PRInt32 *widthOut, PRInt32 *heightOut,
+                                                           nsIURI **uriOut, PRBool *forceWriteOnlyOut)
+{
+    nsresult rv;
+
+    nsCOMPtr<imgIContainer> imgContainer;
+
+    nsCOMPtr<nsIImageLoadingContent> imageLoader = do_QueryInterface(imgElt);
+    if (imageLoader) {
+        nsCOMPtr<imgIRequest> imgRequest;
+        rv = imageLoader->GetRequest(nsIImageLoadingContent::CURRENT_REQUEST,
+                                     getter_AddRefs(imgRequest));
+        NS_ENSURE_SUCCESS(rv, rv);
+        if (!imgRequest)
+            // XXX ERRMSG we need to report an error to developers here! (bug 329026)
+            return NS_ERROR_NOT_AVAILABLE;
+
+        nsCOMPtr<nsIURI> uri;
+        rv = imageLoader->GetCurrentURI(uriOut);
+        NS_ENSURE_SUCCESS(rv, rv);
+       
+        *forceWriteOnlyOut = PR_FALSE;
+
+        rv = imgRequest->GetImage(getter_AddRefs(imgContainer));
+        NS_ENSURE_SUCCESS(rv, rv);
+    } else {
+        // maybe a canvas
+        nsCOMPtr<nsICanvasElement> canvas = do_QueryInterface(imgElt);
+        if (canvas) {
+            PRUint32 w, h;
+            rv = canvas->GetSize(&w, &h);
+            NS_ENSURE_SUCCESS(rv, rv);
+
+            PRUint8 *data = (PRUint8*) PR_Malloc(w * h * 4);
+            cairo_surface_t *surf =
+                cairo_image_surface_create_for_data (data, CAIRO_FORMAT_ARGB32,
+                                                     w, h, w*4);
+            cairo_t *cr = cairo_create (surf);
+            cairo_set_operator (cr, CAIRO_OPERATOR_CLEAR);
+            cairo_paint (cr);
+            cairo_destroy (cr);
+
+            rv = canvas->RenderContextsToSurface(surf);
+            if (NS_FAILED(rv)) {
+                cairo_surface_destroy (surf);
+                return rv;
+            }
+
+            *aCairoSurface = surf;
+            *imgData = data;
+            *widthOut = w;
+            *heightOut = h;
+
+            *uriOut = nsnull;
+            *forceWriteOnlyOut = canvas->IsWriteOnly();
+
+            return NS_OK;
+        } else {
+            NS_WARNING("No way to get surface from non-canvas, non-imageloader");
+            return NS_ERROR_NOT_AVAILABLE;
+        }
+    }
+
+    if (!imgContainer)
+        return NS_ERROR_NOT_AVAILABLE;
+
+    nsCOMPtr<gfxIImageFrame> frame;
+    rv = imgContainer->GetCurrentFrame(getter_AddRefs(frame));
+    NS_ENSURE_SUCCESS(rv, rv);
+
+    nsCOMPtr<nsIImage> img(do_GetInterface(frame));
+
+    PRInt32 imgWidth, imgHeight;
+    rv = frame->GetWidth(&imgWidth);
+    rv |= frame->GetHeight(&imgHeight);
+    if (NS_FAILED(rv))
+        return NS_ERROR_FAILURE;
+
+    if (widthOut)
+        *widthOut = imgWidth;
+    if (heightOut)
+        *heightOut = imgHeight;
+
+#ifdef MOZ_CAIRO_GFX
+    gfxASurface* gfxsurf = nsnull;
+    rv = img->GetSurface(&gfxsurf);
+    NS_ENSURE_SUCCESS(rv, rv);
+
+    *aCairoSurface = gfxsurf->CairoSurface();
+    cairo_surface_reference (*aCairoSurface);
+    *imgData = nsnull;
+#else
+    //
+    // We now need to create a cairo_surface with the same data as
+    // this image element.
+    //
+
+    PRUint8 *cairoImgData = (PRUint8 *)nsMemory::Alloc(imgHeight * imgWidth * 4);
+    PRUint8 *outData = cairoImgData;
+
+    gfx_format format;
+    rv = frame->GetFormat(&format);
+    NS_ENSURE_SUCCESS(rv, rv);
+
+    rv = frame->LockImageData();
+    if (img->GetHasAlphaMask())
+        rv |= frame->LockAlphaData();
+    if (NS_FAILED(rv)) {
+        nsMemory::Free(cairoImgData);
+        return NS_ERROR_FAILURE;
+    }
+
+    PRUint8 *inPixBits, *inAlphaBits = nsnull;
+    PRUint32 inPixStride, inAlphaStride = 0;
+    inPixBits = img->GetBits();
+    inPixStride = img->GetLineStride();
+    if (img->GetHasAlphaMask()) {
+        inAlphaBits = img->GetAlphaBits();
+        inAlphaStride = img->GetAlphaLineStride();
+    }
+
+    PRBool topToBottom = img->GetIsRowOrderTopToBottom();
+    PRBool useBGR;
+
+    // The gtk backend optimizes away the alpha mask of images
+    // with a fully opaque alpha, but doesn't update its format (bug?);
+    // you end up with a RGB_A8 image with GetHasAlphaMask() == false.
+    // We need to treat that case as RGB.
+
+    if ((format == gfxIFormats::RGB || format == gfxIFormats::BGR) ||
+        (!(img->GetHasAlphaMask()) && (format == gfxIFormats::RGB_A8 || format == gfxIFormats::BGR_A8)))
+    {
+        useBGR = (format & 1);
+
+#ifdef IS_BIG_ENDIAN
+        useBGR = !useBGR;
+#endif
+
+        for (PRUint32 j = 0; j < (PRUint32) imgHeight; j++) {
+            PRUint32 rowIndex;
+            if (topToBottom)
+                rowIndex = j;
+            else
+                rowIndex = imgHeight - j - 1;
+
+            PRUint8 *inrowrgb = inPixBits + (inPixStride * rowIndex);
+
+            for (PRUint32 i = 0; i < (PRUint32) imgWidth; i++) {
+                // handle rgb data; no alpha to premultiply
+#ifdef XP_MACOSX
+                // skip extra OSX byte
+                inrowrgb++;
+#endif
+                PRUint8 r, g, b;
+                if (useBGR) {
+                    b = *inrowrgb++;
+                    g = *inrowrgb++;
+                    r = *inrowrgb++;
+                } else {
+                    r = *inrowrgb++;
+                    g = *inrowrgb++;
+                    b = *inrowrgb++;
+                }
+
+#ifdef IS_BIG_ENDIAN
+                // alpha
+                *outData++ = 0xff;
+#endif
+
+                *outData++ = r;
+                *outData++ = g;
+                *outData++ = b;
+
+#ifdef IS_LITTLE_ENDIAN
+                // alpha
+                *outData++ = 0xff;
+#endif
+            }
+        }
+        rv = NS_OK;
+    } else if (format == gfxIFormats::RGB_A1 || format == gfxIFormats::BGR_A1) {
+        useBGR = (format & 1);
+
+#ifdef IS_BIG_ENDIAN
+        useBGR = !useBGR;
+#endif
+
+        for (PRUint32 j = 0; j < (PRUint32) imgHeight; j++) {
+            PRUint32 rowIndex;
+            if (topToBottom)
+                rowIndex = j;
+            else
+                rowIndex = imgHeight - j - 1;
+
+            PRUint8 *inrowrgb = inPixBits + (inPixStride * rowIndex);
+            PRUint8 *inrowalpha = inAlphaBits + (inAlphaStride * rowIndex);
+
+            for (PRUint32 i = 0; i < (PRUint32) imgWidth; i++) {
+                // pull out the bit value into alpha
+                PRInt32 bit = i % 8;
+                PRInt32 byte = i / 8;
+
+#ifdef IS_LITTLE_ENDIAN
+                PRUint8 a = (inrowalpha[byte] >> (7-bit)) & 1;
+#else
+                PRUint8 a = (inrowalpha[byte] >> bit) & 1;
+#endif
+
+#ifdef XP_MACOSX
+                // skip extra X8 byte on OSX
+                inrowrgb++;
+#endif
+
+                // handle rgb data; need to multiply the alpha out,
+                // but we short-circuit that here since we know that a
+                // can only be 0 or 1
+                if (a) {
+                    PRUint8 r, g, b;
+
+                    if (useBGR) {
+                        b = *inrowrgb++;
+                        g = *inrowrgb++;
+                        r = *inrowrgb++;
+                    } else {
+                        r = *inrowrgb++;
+                        g = *inrowrgb++;
+                        b = *inrowrgb++;
+                    }
+
+#ifdef IS_BIG_ENDIAN
+                    // alpha
+                    *outData++ = 0xff;
+#endif
+
+                    *outData++ = r;
+                    *outData++ = g;
+                    *outData++ = b;
+
+#ifdef IS_LITTLE_ENDIAN
+                    // alpha
+                    *outData++ = 0xff;
+#endif
+                } else {
+                    // alpha is 0, so we need to write all 0's,
+                    // ignoring input color
+                    inrowrgb += 3;
+                    *outData++ = 0;
+                    *outData++ = 0;
+                    *outData++ = 0;
+                    *outData++ = 0;
+                }
+            }
+        }
+        rv = NS_OK;
+    } else if (format == gfxIFormats::RGB_A8 || format == gfxIFormats::BGR_A8) {
+        useBGR = (format & 1);
+
+#ifdef IS_BIG_ENDIAN
+        useBGR = !useBGR;
+#endif
+
+        for (PRUint32 j = 0; j < (PRUint32) imgHeight; j++) {
+            PRUint32 rowIndex;
+            if (topToBottom)
+                rowIndex = j;
+            else
+                rowIndex = imgHeight - j - 1;
+
+            PRUint8 *inrowrgb = inPixBits + (inPixStride * rowIndex);
+            PRUint8 *inrowalpha = inAlphaBits + (inAlphaStride * rowIndex);
+
+            for (PRUint32 i = 0; i < (PRUint32) imgWidth; i++) {
+                // pull out alpha; we'll need it to premultiply
+                PRUint8 a = *inrowalpha++;
+
+                // handle rgb data; we need to fully premultiply
+                // with the alpha
+#ifdef XP_MACOSX
+                // skip extra X8 byte on OSX
+                inrowrgb++;
+#endif
+
+                // XXX gcc bug: gcc seems to push "r" into a register
+                // early, and pretends that it's in that register
+                // throughout the 3 macros below.  At the end
+                // of the 3rd macro, the correct r value is
+                // calculated but never stored anywhere -- the r variable
+                // has the value of the low byte of register that it
+                // was stuffed into, which has the result of some 
+                // intermediate calculation.
+                // I've seen this on gcc 3.4.2 x86 (Fedora Core 3)
+                // and gcc 3.3 PPC (OS X 10.3)
+
+                //PRUint8 b, g, r;
+                //FAST_DIVIDE_BY_255(b, *inrowrgb++ * a - a / 2);
+                //FAST_DIVIDE_BY_255(g, *inrowrgb++ * a - a / 2);
+                //FAST_DIVIDE_BY_255(r, *inrowrgb++ * a - a / 2);
+
+                PRUint8 r, g, b;
+                if (useBGR) {
+                    b = (*inrowrgb++ * a - a / 2) / 255;
+                    g = (*inrowrgb++ * a - a / 2) / 255;
+                    r = (*inrowrgb++ * a - a / 2) / 255;
+                } else {
+                    r = (*inrowrgb++ * a - a / 2) / 255;
+                    g = (*inrowrgb++ * a - a / 2) / 255;
+                    b = (*inrowrgb++ * a - a / 2) / 255;
+                }
+
+#ifdef IS_BIG_ENDIAN
+                *outData++ = a;
+#endif
+
+                *outData++ = r;
+                *outData++ = g;
+                *outData++ = b;
+
+#ifdef IS_LITTLE_ENDIAN
+                *outData++ = a;
+#endif
+            }
+        }
+        rv = NS_OK;
+    } else {
+        rv = NS_ERROR_FAILURE;
+    }
+
+    if (img->GetHasAlphaMask())
+        frame->UnlockAlphaData();
+    frame->UnlockImageData();
+
+    if (NS_FAILED(rv)) {
+        nsMemory::Free(cairoImgData);
+        return rv;
+    }
+
+    cairo_surface_t *imgSurf =
+        cairo_image_surface_create_for_data(cairoImgData, CAIRO_FORMAT_ARGB32,
+                                            imgWidth, imgHeight, imgWidth*4);
+
+    *aCairoSurface = imgSurf;
+    *imgData = cairoImgData;
+#endif
+
+    return NS_OK;
+}
+
+void
+nsCanvasRenderingContextGLPrivate::DoDrawImageSecurityCheck(nsIURI* aURI, PRBool forceWriteOnly)
+{
+    /* So; this is causing dll woes under win32.  Until we figure that out, we just return. */
+    return;
+
+#if 0
+    fprintf (stderr, "DoDrawImageSecuritycheck this 1: %p\n", this);
+    if (mCanvasElement->IsWriteOnly())
+        return;
+
+    fprintf (stderr, "DoDrawImageSecuritycheck this 2: %p\n", this);
+    if (!aURI)
+        return;
+
+    fprintf (stderr, "DoDrawImageSecuritycheck this 3: %p\n", this);
+    if (forceWriteOnly) {
+        mCanvasElement->SetWriteOnly();
+        return;
+    }
+
+    fprintf (stderr, "DoDrawImageSecuritycheck this 4: %p\n", this);
+    nsCOMPtr<nsIScriptSecurityManager> ssm =
+        do_GetService(NS_SCRIPTSECURITYMANAGER_CONTRACTID);
+    if (!ssm) {
+        mCanvasElement->SetWriteOnly();
+        return;
+    }
+
+    fprintf (stderr, "DoDrawImageSecuritycheck this 5: %p\n", this);
+#ifdef MOZILLA_1_8_BRANCH
+#if 0
+    nsCOMPtr<nsIDOMNode> elem = do_QueryInterface(mCanvasElement);
+    if (elem && ssm) {
+        nsCOMPtr<nsIPrincipal> elemPrincipal;
+        nsCOMPtr<nsIPrincipal> uriPrincipal;
+        nsCOMPtr<nsIDocument> elemDocument;
+        nsContentUtils::GetDocumentAndPrincipal(elem, getter_AddRefs(elemDocument), getter_AddRefs(elemPrincipal));
+        ssm->GetCodebasePrincipal(aURI, getter_AddRefs(uriPrincipal));
+
+        if (uriPrincipal && elemPrincipal) {
+            nsresult rv =
+                ssm->CheckSameOriginPrincipal(elemPrincipal, uriPrincipal);
+            if (NS_SUCCEEDED(rv)) {
+                // Same origin
+                return;
+            }
+        }
+    }
+#endif
+#else
+    nsCOMPtr<nsINode> elem = do_QueryInterface(mCanvasElement);
+    if (elem && ssm) {
+        nsCOMPtr<nsIPrincipal> uriPrincipal;
+        ssm->GetCodebasePrincipal(aURI, getter_AddRefs(uriPrincipal));
+
+        if (uriPrincipal) {
+            nsresult rv = ssm->CheckSameOriginPrincipal(elem->NodePrincipal(),
+                                                        uriPrincipal);
+            if (NS_SUCCEEDED(rv)) {
+                // Same origin
+                return;
+            }
+        }
+    }
+#endif
+
+    fprintf (stderr, "DoDrawImageSecuritycheck this 6: %p\n", this); fflush(stderr);
+    mCanvasElement->SetWriteOnly();
+#endif
+}
+
+
+nsCanvasRenderingContextGLPrivate::nsCanvasRenderingContextGLPrivate()
+    : mGlitzContext(nsnull),
+      mGlitzDrawable(nsnull),
+      mContextToken(nsnull),
+      mCurrent(PR_FALSE),
+      mWidth(0), mHeight(0), mStride(0), mImageBuffer(nsnull),
+      mCanvasElement(nsnull), mGlitzSurface(nsnull), mGlitzImageBuffer(nsnull),
+      mCairoImageSurface(nsnull)
+{
+    if (!gGlitzInitialized) {
+#ifdef MOZ_X11
+        glitz_glx_init("libGL.so.1");
+#endif
+#ifdef XP_WIN
+        glitz_wgl_init(NULL);
+#endif
+        gGlitzInitialized = PR_TRUE;
+    }
+
+    // grab the xpconnect service
+    if (!gXPConnect) {
+        nsresult rv = CallGetService(nsIXPConnect::GetCID(), &gXPConnect);
+        if (NS_FAILED(rv)) {
+            NS_ERROR("Failed to get XPConnect!");
+            return;
+        }
+    } else {
+        NS_ADDREF(gXPConnect);
+    }
+
+    if (!gJSRuntimeService) {
+        nsresult rv = CallGetService("@mozilla.org/js/xpc/RuntimeService;1",
+                                     &gJSRuntimeService);
+        if (NS_FAILED(rv)) {
+            // uh..
+            NS_ERROR("Failed to get JS RuntimeService!");
+            return;
+        }
+
+        gJSRuntimeService->GetRuntime(&gScriptRuntime);
+        if (!gScriptRuntime) {
+            NS_RELEASE(gJSRuntimeService);
+            gJSRuntimeService = nsnull;
+            NS_ERROR("Unable to get JS runtime from JS runtime service");
+        }
+    } else {
+        NS_ADDREF(gJSRuntimeService);
+    }
+
+#ifdef XP_WIN
+    mWinBitmap = nsnull;
+    mWinBitmapDC = nsnull;
+#endif
+}
+
+nsCanvasRenderingContextGLPrivate::~nsCanvasRenderingContextGLPrivate()
+{
+    Destroy();
+
+    if (gXPConnect && gXPConnect->Release() == 0)
+        gXPConnect = nsnull;
+    if (gJSRuntimeService && gJSRuntimeService->Release() == 0) {
+        gJSRuntimeService = nsnull;
+        gScriptRuntime = nsnull;
+    }
+}
+
+nsresult
+nsCanvasRenderingContextGLPrivate::DoSwapBuffers()
+{
+    if (!mImageBuffer)
+        return NS_OK;
+
+    MakeContextCurrent();
+
+    // call glitz_get_pixels to pull out the pixels
+    glitz_pixel_format_t argb_pf =
+        { GLITZ_FOURCC_RGB,
+          { 32, 0xff000000, 0x00ff0000, 0x0000ff00, 0x000000ff },
+          0,
+          0,
+          mStride,
+          GLITZ_PIXEL_SCANLINE_ORDER_TOP_DOWN
+        };
+
+    glitz_pixel_format_t *pf = &argb_pf;
+
+    glitz_get_pixels (mGlitzSurface,
+                      0, 0, mWidth, mHeight, pf, mGlitzImageBuffer);
+
+    // then invalidate the region and do a sync redraw
+    // (uh, why sync?)
+    nsIFrame *frame = GetCanvasLayoutFrame();
+    if (frame) {
+        nsRect r = frame->GetRect();
+        r.x = r.y = 0;
+
+        // sync redraw
+        //frame->Invalidate(r, PR_TRUE);
+
+        // nsIFrame::Invalidate is an internal non-virtual method,
+        // so we basically recreate it here.  I would suggest
+        // an InvalidateExternal for the trunk.
+        nsIPresShell *shell = frame->GetPresContext()->GetPresShell();
+        if (shell) {
+            PRBool suppressed = PR_FALSE;
+            shell->IsPaintingSuppressed(&suppressed);
+            if (suppressed)
+                return NS_OK;
+        }
+
+        // maybe VMREFRESH_IMMEDIATE in some cases,
+        // need to think
+        PRUint32 flags = NS_VMREFRESH_NO_SYNC;
+        if (frame->HasView()) {
+            nsIView* view = frame->GetViewExternal();
+            view->GetViewManager()->UpdateView(view, r, flags);
+        } else {
+            nsPoint offset;
+            nsIView *view;
+            frame->GetOffsetFromView(offset, &view);
+            NS_ASSERTION(view, "no view");
+            r += offset;
+            view->GetViewManager()->UpdateView(view, r, flags);
+        }
+    }
+
+    return NS_OK;
+}
+
+PRBool
+nsCanvasRenderingContextGLPrivate::SafeToCreateCanvas3DContext()
+{
+    nsresult rv;
+
+    // first see if we're a chrome context
+    PRBool is_caller_chrome = PR_FALSE;
+    nsCOMPtr<nsIScriptSecurityManager> ssm =
+        do_GetService(NS_SCRIPTSECURITYMANAGER_CONTRACTID, &rv);
+    NS_ENSURE_SUCCESS(rv, PR_FALSE);
+
+    rv = ssm->SubjectPrincipalIsSystem(&is_caller_chrome);
+    if (NS_SUCCEEDED(rv) && is_caller_chrome)
+        return TRUE;
+
+    // not chrome? check pref.
+
+    // check whether it's safe to create a 3d context via a pref
+    nsCOMPtr<nsIPrefService> prefService = do_GetService(NS_PREFSERVICE_CONTRACTID, &rv);
+    NS_ENSURE_SUCCESS(rv, PR_FALSE);
+
+    // our pref is 'extensions.canvas3d.enabledForWebContent'
+    nsCOMPtr<nsIPrefBranch> prefBranch;
+    rv = prefService->GetBranch("extensions.canvas3d.", getter_AddRefs(prefBranch));
+    NS_ENSURE_SUCCESS(rv, PR_FALSE);
+
+    PRBool enabled;
+    rv = prefBranch->GetBoolPref("enabledForWebContent", &enabled);
+    NS_ENSURE_SUCCESS(rv, PR_FALSE);
+
+    if (enabled)
+        return PR_TRUE;
+
+    return PR_FALSE;
+}
new file mode 100644
--- /dev/null
+++ b/extensions/canvas3d/src/nsCanvasRenderingContextGL.h
@@ -0,0 +1,647 @@
+/* -*- 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 _NSCANVASRENDERINGCONTEXTGL_H_
+#define _NSCANVASRENDERINGCONTEXTGL_H_
+
+#include "nsICanvasRenderingContextGL.h"
+#include "nsICanvasRenderingContextInternal.h"
+#include "nsIDOMHTMLCanvasElement.h"
+
+#include "nsICanvasGLPrivate.h"
+
+#include "nsIScriptSecurityManager.h"
+#include "nsISecurityCheckedComponent.h"
+
+#include "nsWeakReference.h"
+
+#include "imgIRequest.h"
+#include "imgIContainer.h"
+#include "gfxIImageFrame.h"
+#include "nsIDOMHTMLCanvasElement.h"
+#include "nsICanvasElement.h"
+#include "nsIDOMHTMLImageElement.h"
+#include "nsIImageLoadingContent.h"
+#include "nsIInterfaceRequestorUtils.h"
+#include "nsIImage.h"
+#include "nsIFrame.h"
+#include "nsDOMError.h"
+#include "nsIJSRuntimeService.h"
+
+#include "nsDOMError.h"
+
+#include "nsContentUtils.h"
+
+#include "nsIXPConnect.h"
+#include "jsapi.h"
+
+#include "cairo.h"
+#include "glitz.h"
+#include "glew.h"
+
+#ifdef XP_WIN
+#include <windows.h>
+#endif
+
+extern nsIXPConnect *gXPConnect;
+extern JSRuntime *gScriptRuntime;
+extern nsIJSRuntimeService *gJSRuntimeService;
+extern PRBool gGlitzInitialized;
+
+class nsCanvasRenderingContextGLES11;
+class nsCanvasRenderingContextGLWeb20;
+
+class nsCanvasRenderingContextGLPrivate :
+    public nsICanvasRenderingContextInternal,
+    public nsSupportsWeakReference
+{
+public:
+    nsCanvasRenderingContextGLPrivate();
+    virtual ~nsCanvasRenderingContextGLPrivate();
+
+    virtual nsICanvasRenderingContextGL *GetSelf() = 0;
+
+    virtual PRBool ValidateGL() { return PR_TRUE; }
+
+    inline void MakeContextCurrent();
+    static void LostCurrentContext(void *closure);
+
+    inline GLEWContext *glewGetContext() {
+        return &mGlewContext;
+    }
+
+    // nsICanvasRenderingContextInternal
+    NS_IMETHOD SetCanvasElement(nsICanvasElement* aParentCanvas);
+    NS_IMETHOD SetDimensions(PRInt32 width, PRInt32 height);
+    NS_IMETHOD Render(nsIRenderingContext *rc);
+    NS_IMETHOD RenderToSurface(cairo_surface_t *surf);
+    NS_IMETHOD GetInputStream(const nsACString& aMimeType,
+                              const nsAString& aEncoderOptions,
+                              nsIInputStream **aStream);
+
+protected:
+    PRBool SafeToCreateCanvas3DContext();
+
+    virtual void Destroy();
+
+    nsIFrame *GetCanvasLayoutFrame();
+
+    nsresult DoSwapBuffers();
+
+    nsresult CairoSurfaceFromElement(nsIDOMElement *imgElt,
+                                     cairo_surface_t **aCairoSurface,
+                                     PRUint8 **imgData,
+                                     PRInt32 *widthOut, PRInt32 *heightOut,
+                                     nsIURI **uriOut, PRBool *forceWriteOnlyOut);
+    void DoDrawImageSecurityCheck(nsIURI* aURI, PRBool forceWriteOnly);
+
+    GLEWContext mGlewContext;
+
+    glitz_context_t* mGlitzContext;
+    glitz_drawable_t* mGlitzDrawable;
+
+    void *mContextToken;
+
+    PRPackedBool mCurrent;
+
+    PRInt32 mWidth, mHeight, mStride;
+    PRUint8 *mImageBuffer;
+
+    nsICanvasElement* mCanvasElement;
+
+    glitz_surface_t* mGlitzSurface;
+    glitz_buffer_t* mGlitzImageBuffer;
+
+    cairo_surface_t *mCairoImageSurface;
+
+#ifdef XP_WIN
+    HBITMAP mWinBitmap;
+    HDC mWinBitmapDC;
+#endif
+
+    static inline PRBool JSValToFloatArray (JSContext *ctx, jsval val,
+                                            jsuint cnt, float *array)
+    {
+        JSObject *arrayObj;
+        jsuint arrayLen;
+        jsval jv;
+        jsdouble dv;
+
+        if (!::JS_ValueToObject(ctx, val, &arrayObj) ||
+            !::JS_IsArrayObject(ctx, arrayObj) ||
+            !::JS_GetArrayLength(ctx, arrayObj, &arrayLen) ||
+            (arrayLen < cnt))
+            return PR_FALSE;
+
+        for (jsuint i = 0; i < cnt; i++) {
+            ::JS_GetElement(ctx, arrayObj, i, &jv);
+            if (!::JS_ValueToNumber(ctx, jv, &dv))
+                return PR_FALSE;
+            array[i] = (float) dv;
+        }
+
+        return PR_TRUE;
+    }
+
+    static inline PRBool JSValToDoubleArray (JSContext *ctx, jsval val,
+                                             jsuint cnt, double *array)
+    {
+        JSObject *arrayObj;
+        jsuint arrayLen;
+        jsval jv;
+        jsdouble dv;
+
+        if (!::JS_ValueToObject(ctx, val, &arrayObj) ||
+            !::JS_IsArrayObject(ctx, arrayObj) ||
+            !::JS_GetArrayLength(ctx, arrayObj, &arrayLen) ||
+            (arrayLen < cnt))
+            return PR_FALSE;
+
+        for (jsuint i = 0; i < cnt; i++) {
+            ::JS_GetElement(ctx, arrayObj, i, &jv);
+            if (!::JS_ValueToNumber(ctx, jv, &dv))
+                return PR_FALSE;
+            array[i] = dv;
+        }
+
+        return PR_TRUE;
+    }
+
+    static inline PRBool JSValToJSArrayAndLength (JSContext *ctx, jsval val,
+                                                  JSObject **outObj, jsuint *outLen)
+    {
+        JSObject *obj = nsnull;
+        jsuint len;
+        if (!::JS_ValueToObject(ctx, val, &obj) ||
+            !::JS_IsArrayObject(ctx, obj) ||
+            !::JS_GetArrayLength(ctx, obj, &len))
+        {
+            return PR_FALSE;
+        }
+
+        *outObj = obj;
+        *outLen = len;
+
+        return PR_TRUE;
+    }
+
+    template<class T>
+    static nsresult JSValToSpecificInterface(JSContext *ctx, jsval val, T **out)
+    {
+        if (JSVAL_IS_NULL(val)) {
+            *out = nsnull;
+            return NS_OK;
+        }
+
+        if (!JSVAL_IS_OBJECT(val))
+            return NS_ERROR_DOM_SYNTAX_ERR;
+
+        nsCOMPtr<nsISupports> isup;
+        nsresult rv = gXPConnect->WrapJS(ctx, JSVAL_TO_OBJECT(val),
+                                         NS_GET_IID(nsISupports),
+                                         getter_AddRefs(isup));
+        if (NS_FAILED(rv))
+            return NS_ERROR_DOM_SYNTAX_ERR;
+
+        nsCOMPtr<T> obj = do_QueryInterface(isup);
+        if (!obj)
+            return NS_ERROR_DOM_SYNTAX_ERR;
+
+        NS_ADDREF(*out = obj.get());
+        return NS_OK;
+    }
+
+    static inline JSObject *ArrayToJSArray (JSContext *ctx,
+                                            const PRInt32 *vals,
+                                            const PRUint32 len)
+    {
+        // XXX handle ints that are too big to fit
+        nsAutoArrayPtr<jsval> jsvector(new jsval[len]);
+        for (PRUint32 i = 0; i < len; i++)
+            jsvector[i] = INT_TO_JSVAL(vals[i]);
+        return JS_NewArrayObject(ctx, len, jsvector);
+    }
+
+    static inline JSObject *ArrayToJSArray (JSContext *ctx,
+                                            const PRUint32 *vals,
+                                            const PRUint32 len)
+    {
+        // XXX handle ints that are too big to fit
+        nsAutoArrayPtr<jsval> jsvector(new jsval[len]);
+        for (PRUint32 i = 0; i < len; i++)
+            jsvector[i] = INT_TO_JSVAL(vals[i]);
+        return JS_NewArrayObject(ctx, len, jsvector);
+    }
+};
+
+class NativeJSContext {
+public:
+    NativeJSContext() {
+        error = gXPConnect->GetCurrentNativeCallContext(getter_AddRefs(ncc));
+        if (NS_FAILED(error))
+            return;
+
+        if (!ncc) {
+            error = NS_ERROR_FAILURE;
+            return;
+        }
+
+        ctx = nsnull;
+
+        error = ncc->GetJSContext(&ctx);
+        if (NS_FAILED(error))
+            return;
+
+        ncc->GetArgc(&argc);
+        ncc->GetArgvPtr(&argv);
+    }
+
+    PRBool AddGCRoot (void *aPtr, const char *aName) {
+        return JS_AddNamedRootRT(gScriptRuntime, aPtr, aName);
+    }
+
+    void ReleaseGCRoot (void *aPtr) {
+        JS_RemoveRootRT(gScriptRuntime, aPtr);
+    }
+
+    void SetRetVal (PRInt32 val) {
+        if (INT_FITS_IN_JSVAL(val))
+            SetRetVal(INT_TO_JSVAL(val));
+        else
+            SetRetVal((double) val);
+    }
+
+    void SetRetVal (PRUint32 val) {
+        if (INT_FITS_IN_JSVAL(val))
+            SetRetVal(INT_TO_JSVAL((int) val));
+        else
+            SetRetVal((double) val);
+    }
+
+    void SetRetVal (double val) {
+        jsval *vp;
+        ncc->GetRetValPtr(&vp);
+        JS_NewDoubleValue(ctx, val, vp);
+    }
+
+    void SetBoolRetVal (PRBool val) {
+        if (val)
+            SetRetVal(JSVAL_TRUE);
+        else
+            SetRetVal(JSVAL_FALSE);
+    }
+
+    void SetRetVal (PRInt32 *vp, PRUint32 len) {
+        nsAutoArrayPtr<jsval> jsvector = new jsval[len];
+        for (PRUint32 i = 0; i < len; i++)
+            jsvector[i] = INT_TO_JSVAL(vp[i]);
+        JSObject *jsarr = JS_NewArrayObject(ctx, len, jsvector.get());
+        SetRetVal(OBJECT_TO_JSVAL(jsarr));
+    }
+
+    void SetRetVal (float *fp, PRUint32 len) {
+        nsAutoArrayPtr<jsval> jsvector = new jsval[len];
+
+        if (!JS_EnterLocalRootScope(ctx))
+            return; // XXX ???
+
+        for (PRUint32 i = 0; i < len; i++)
+            JS_NewDoubleValue(ctx, (jsdouble) fp[i], &jsvector[i]);
+        JSObject *jsarr = JS_NewArrayObject(ctx, len, jsvector.get());
+        SetRetVal(OBJECT_TO_JSVAL(jsarr));
+
+        JS_LeaveLocalRootScope(ctx);
+    }
+
+    void SetRetVal (jsval val) {
+        jsval *vp;
+        ncc->GetRetValPtr(&vp);
+        *vp = val;
+        ncc->SetReturnValueWasSet(PR_TRUE);
+    }
+
+    nsCOMPtr<nsIXPCNativeCallContext> ncc;
+    nsresult error;
+    JSContext *ctx;
+    PRUint32 argc;
+    jsval *argv;
+};
+
+class JSObjectHelper {
+public:
+    JSObjectHelper(NativeJSContext *jsctx)
+        : mCtx (jsctx)
+    {
+        mObject = JS_NewObject(mCtx->ctx, NULL, NULL, NULL);
+        if (!mObject)
+            return;
+
+        if (!mCtx->AddGCRoot(&mObject, "JSObjectHelperCanvas3D"))
+            mObject = nsnull;
+    }
+
+    ~JSObjectHelper() {
+        if (mObject && mCtx)
+            mCtx->ReleaseGCRoot(&mObject);
+    }
+
+    PRBool DefineProperty(const char *name, PRInt32 val) {
+        // XXX handle too big ints
+        if (!JS_DefineProperty(mCtx->ctx, mObject, name, INT_TO_JSVAL(val), NULL, NULL, JSPROP_ENUMERATE))
+            return PR_FALSE;
+        return PR_TRUE;
+    }
+
+    PRBool DefineProperty(const char *name, PRUint32 val) {
+        // XXX handle too big ints
+        if (!JS_DefineProperty(mCtx->ctx, mObject, name, INT_TO_JSVAL((int)val), NULL, NULL, JSPROP_ENUMERATE))
+            return PR_FALSE;
+        return PR_TRUE;
+    }
+
+    PRBool DefineProperty(const char *name, double val) {
+        jsval dv;
+
+        if (!JS_NewDoubleValue(mCtx->ctx, val, &dv))
+            return PR_FALSE;
+
+        if (!JS_DefineProperty(mCtx->ctx, mObject, name, dv, NULL, NULL, JSPROP_ENUMERATE))
+            return PR_FALSE;
+        return PR_TRUE;
+    }
+
+    PRBool DefineProperty(const char *name, JSObject *val) {
+        if (!JS_DefineProperty(mCtx->ctx, mObject, name, OBJECT_TO_JSVAL(val), NULL, NULL, JSPROP_ENUMERATE))
+            return PR_FALSE;
+        return PR_TRUE;
+    }
+
+    // Blah.  We can't name this DefineProperty also because PRBool is the same as PRInt32
+    PRBool DefineBoolProperty(const char *name, PRBool val) {
+        if (!JS_DefineProperty(mCtx->ctx, mObject, name, val ? JS_TRUE : JS_FALSE, NULL, NULL, JSPROP_ENUMERATE))
+            return PR_FALSE;
+        return PR_TRUE;
+    }
+
+    PRBool DefineProperty(const char *name, const nsCSubstring& val) {
+        JSString *jsstr = JS_NewStringCopyN(mCtx->ctx, val.BeginReading(), val.Length());
+        if (!jsstr ||
+            !JS_DefineProperty(mCtx->ctx, mObject, name, STRING_TO_JSVAL(jsstr), NULL, NULL, JSPROP_ENUMERATE))
+            return PR_FALSE;
+        return PR_TRUE;
+    }
+
+    PRBool DefineProperty(const char *name, const nsSubstring& val) {
+        JSString *jsstr = JS_NewUCStringCopyN(mCtx->ctx, val.BeginReading(), val.Length());
+        if (!jsstr ||
+            !JS_DefineProperty(mCtx->ctx, mObject, name, STRING_TO_JSVAL(jsstr), NULL, NULL, JSPROP_ENUMERATE))
+            return PR_FALSE;
+        return PR_TRUE;
+    }
+
+    PRBool DefineProperty(const char *name, const char *val, PRUint32 len) {
+        JSString *jsstr = JS_NewStringCopyN(mCtx->ctx, val, len);
+        if (!jsstr ||
+            !JS_DefineProperty(mCtx->ctx, mObject, name, STRING_TO_JSVAL(jsstr), NULL, NULL, JSPROP_ENUMERATE))
+            return PR_FALSE;
+        return PR_TRUE;
+    }
+
+    JSObject *Object() {
+        return mObject;
+    }
+
+protected:
+    NativeJSContext *mCtx;
+    JSObject *mObject;
+};
+
+class SimpleBuffer {
+public:
+    SimpleBuffer() : type(GL_FLOAT), data(nsnull), length(0), capacity(0), sizePerVertex(0) {
+    }
+
+    ~SimpleBuffer() {
+        Release();
+    }
+
+    inline PRUint32 ElementSize() {
+        if (type == GL_FLOAT) return sizeof(float);
+        if (type == GL_SHORT) return sizeof(short);
+        if (type == GL_UNSIGNED_SHORT) return sizeof(unsigned short);
+        if (type == GL_BYTE) return 1;
+        if (type == GL_UNSIGNED_BYTE) return 1;
+        if (type == GL_INT) return sizeof(int);
+        if (type == GL_UNSIGNED_INT) return sizeof(unsigned int);
+        if (type == GL_DOUBLE) return sizeof(double);
+        return 0;
+    }
+
+    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 {
+            EnsureCapacity(PR_FALSE, count*ElementSize());
+            type = t;
+            length = count;
+            sizePerVertex = spv;
+        }
+    }
+
+    void Release() {
+        if (data)
+            PR_Free(data);
+        length = 0;
+        capacity = 0;
+        data = nsnull;
+    }
+
+    void EnsureCapacity(PRBool preserve, PRUint32 cap) {
+        if (capacity >= cap)
+            return;
+
+        void* newdata = PR_Malloc(cap);
+        if (preserve && length)
+            memcpy(newdata, data, length*ElementSize());
+        PR_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
+};
+
+
+nsresult JSArrayToSimpleBuffer (SimpleBuffer& sbuffer,
+                                PRUint32 typeParam,
+                                PRUint32 sizeParam,
+                                JSContext *ctx,
+                                JSObject *arrayObj,
+                                jsuint arrayLen);
+
+class CanvasGLTexture :
+    public nsICanvasRenderingContextGLTexture,
+    public nsICanvasGLTexture
+{
+    friend class nsCanvasRenderingContextGLES11;
+    friend class nsCanvasRenderingContextGLWeb20;
+public:
+    CanvasGLTexture(nsCanvasRenderingContextGLPrivate *owner);
+    ~CanvasGLTexture();
+
+    NS_DECL_ISUPPORTS
+
+    NS_DECL_NSICANVASRENDERINGCONTEXTGLTEXTURE
+
+    nsresult Init();
+    nsresult Dispose();
+
+protected:
+    PRBool mDisposed;
+    nsCOMPtr<nsIWeakReference> mOwnerContext;
+
+    glitz_surface_t *mGlitzTextureSurface;
+    glitz_texture_object_t *mGlitzTextureObject;
+    PRUint32 mWidth;
+    PRUint32 mHeight;
+};
+
+class CanvasGLBuffer :
+    public nsICanvasRenderingContextGLBuffer,
+    public nsISecurityCheckedComponent,
+    public nsICanvasGLBuffer
+{
+    friend class nsCanvasRenderingContextGLES11;
+    friend class nsCanvasRenderingContextGLWeb20;
+public:
+
+    CanvasGLBuffer(nsCanvasRenderingContextGLPrivate *owner);
+    ~CanvasGLBuffer();
+
+    // Init can be called multiple times to reinitialize this
+    // buffer object
+    nsresult Init (PRUint32 usage,
+                   PRUint32 size,
+                   PRUint32 type,
+                   JSContext *ctx,
+                   JSObject *arrayObj,
+                   jsuint arrayLen);
+
+    SimpleBuffer& GetSimpleBuffer() { return mSimpleBuffer; }
+
+    NS_DECL_ISUPPORTS
+    NS_DECL_NSICANVASRENDERINGCONTEXTGLBUFFER
+    NS_DECL_NSISECURITYCHECKEDCOMPONENT
+
+protected:
+    CanvasGLBuffer() { }
+
+    inline GLEWContext *glewGetContext() {
+        return mGlewContextPtr;
+    }
+
+    nsCOMPtr<nsIWeakReference> mOwnerContext;
+    GLEWContext *mGlewContextPtr;
+
+    PRBool mDisposed;
+
+    PRUint32 mLength;
+    PRUint32 mSize;
+    PRUint32 mType;
+    PRUint32 mUsage;
+
+    SimpleBuffer mSimpleBuffer;
+    GLuint mBufferID;
+};
+
+/* Helper macros for when we're just wrapping a gl method, so that
+ * we can avoid having to type this 500 times.  Note that these MUST
+ * NOT BE USED if we need to check any of the parameters.
+ */
+
+#define GL_SAME_METHOD_0(glname, name)                       \
+NS_IMETHODIMP NSGL_CONTEXT_NAME::name() {       \
+    MakeContextCurrent(); gl##glname(); return NS_OK;        \
+}
+
+#define GL_SAME_METHOD_1(glname, name, t1)                            \
+NS_IMETHODIMP NSGL_CONTEXT_NAME::name(t1 a1) {           \
+    MakeContextCurrent(); gl##glname(a1); return NS_OK;               \
+}
+
+#define GL_SAME_METHOD_2(glname, name, t1, t2)                          \
+NS_IMETHODIMP NSGL_CONTEXT_NAME::name(t1 a1, t2 a2) {      \
+    MakeContextCurrent(); gl##glname(a1,a2); return NS_OK;              \
+}
+
+#define GL_SAME_METHOD_3(glname, name, t1, t2, t3)                        \
+NS_IMETHODIMP NSGL_CONTEXT_NAME::name(t1 a1, t2 a2, t3 a3) { \
+    MakeContextCurrent(); gl##glname(a1,a2,a3); return NS_OK;             \
+}
+
+#define GL_SAME_METHOD_4(glname, name, t1, t2, t3, t4)                           \
+NS_IMETHODIMP NSGL_CONTEXT_NAME::name(t1 a1, t2 a2, t3 a3, t4 a4) { \
+    MakeContextCurrent(); gl##glname(a1,a2,a3,a4); return NS_OK;                 \
+}
+
+#define GL_SAME_METHOD_5(glname, name, t1, t2, t3, t4, t5)                              \
+NS_IMETHODIMP NSGL_CONTEXT_NAME::name(t1 a1, t2 a2, t3 a3, t4 a4, t5 a5) { \
+    MakeContextCurrent(); gl##glname(a1,a2,a3,a4,a5); return NS_OK;                     \
+}
+
+#define GL_SAME_METHOD_6(glname, name, t1, t2, t3, t4, t5, t6)                                 \
+NS_IMETHODIMP NSGL_CONTEXT_NAME::name(t1 a1, t2 a2, t3 a3, t4 a4, t5 a5, t6 a6) { \
+    MakeContextCurrent(); gl##glname(a1,a2,a3,a4,a5,a6); return NS_OK;                         \
+}
+
+#endif /* _NSCANVASRENDERINGCONTEXTGL_H_ */
--- a/extensions/canvas3d/src/nsCanvasRenderingContextGLES11.cpp
+++ b/extensions/canvas3d/src/nsCanvasRenderingContextGLES11.cpp
@@ -36,31 +36,38 @@
  *
  * ***** END LICENSE BLOCK ***** */
 
 #include "prmem.h"
 #include "prlog.h"
 
 #include "nsIRenderingContext.h"
 
+#define NSGL_CONTEXT_NAME nsCanvasRenderingContextGLES11
+
+#include "nsCanvasRenderingContextGL.h"
 #include "nsICanvasRenderingContextGLES11.h"
 #include "nsICanvasRenderingContextInternal.h"
 #include "nsIDOMHTMLCanvasElement.h"
 #include "nsIView.h"
 #include "nsIViewManager.h"
 
+#include "nsICanvasGLPrivate.h"
+
 #ifndef MOZILLA_1_8_BRANCH
 #include "nsIDocument.h"
 #endif
 
 #include "nsTransform2D.h"
 
 #include "nsIScriptSecurityManager.h"
 #include "nsISecurityCheckedComponent.h"
 
+#include "nsWeakReference.h"
+
 #include "imgIRequest.h"
 #include "imgIContainer.h"
 #include "gfxIImageFrame.h"
 #include "nsIDOMHTMLCanvasElement.h"
 #include "nsICanvasElement.h"
 #include "nsIDOMHTMLImageElement.h"
 #include "nsIImageLoadingContent.h"
 #include "nsIInterfaceRequestorUtils.h"
@@ -105,20 +112,16 @@
 #include "cairo-xlib.h"
 #include "glitz-glx.h"
 #endif
 
 #ifdef XP_WIN
 #include "cairo-win32.h"
 #include "glitz-wgl.h"
 
-#ifdef PR_LOGGING
-PRLogModuleInfo* gGLES11Log = nsnull;
-#endif
-
 #ifdef MOZILLA_1_8_BRANCH
 struct _cairo_surface_win32_hack {
     void *ptr;
     unsigned int refcnt;
     cairo_status_t st;
     cairo_bool_t finished;
     /* array_t */
     int sz;
@@ -130,1134 +133,129 @@ struct _cairo_surface_win32_hack {
     unsigned int b;
 
     /* win32 */
     cairo_format_t format;
 };
 #endif
 #endif
 
-static nsIXPConnect *gXPConnect = nsnull;
-static JSRuntime *gScriptRuntime = nsnull;
-static nsIJSRuntimeService *gJSRuntimeService = nsnull;
+#ifdef PR_LOGGING
+PRLogModuleInfo* gGLES11Log = nsnull;
+#endif
 
 #define MAX_TEXTURE_UNITS 16
 
-class nsCanvasRenderingContextGLES11;
-
-class NativeJSContext {
-public:
-    NativeJSContext() {
-        error = gXPConnect->GetCurrentNativeCallContext(getter_AddRefs(ncc));
-        if (NS_FAILED(error))
-            return;
-
-        if (!ncc) {
-            error = NS_ERROR_FAILURE;
-            return;
-        }
-
-        ctx = nsnull;
-
-        error = ncc->GetJSContext(&ctx);
-        if (NS_FAILED(error))
-            return;
-
-        ncc->GetArgc(&argc);
-        ncc->GetArgvPtr(&argv);
-    }
-
-    void addGCRoot (void *aPtr, const char *aName) {
-        PRBool ok = JS_AddNamedRootRT(gScriptRuntime, aPtr, aName);
-        if (!ok) {
-            NS_ERROR("JS_AddNamedRootRT failed!\n");
-            return;
-        }
-    }
-
-    void releaseGCRoot (void *aPtr) {
-        JS_RemoveRootRT(gScriptRuntime, aPtr);
-    }
-
-    nsCOMPtr<nsIXPCNativeCallContext> ncc;
-    nsresult error;
-    JSContext *ctx;
-    PRUint32 argc;
-    jsval *argv;
-};
-
-class SimpleBuffer {
-public:
-    SimpleBuffer() : type(GL_FLOAT), data(nsnull), length(0), capacity(0), sizePerVertex(0) {
-    }
-
-    ~SimpleBuffer() {
-        Release();
-    }
-
-    inline PRUint32 ElementSize() {
-        if (type == GL_FLOAT) return sizeof(float);
-        if (type == GL_SHORT) return sizeof(short);
-        if (type == GL_UNSIGNED_SHORT) return sizeof(unsigned short);
-        if (type == GL_BYTE) return 1;
-        if (type == GL_UNSIGNED_BYTE) return 1;
-        if (type == GL_INT) return sizeof(int);
-        if (type == GL_UNSIGNED_INT) return sizeof(unsigned int);
-        if (type == GL_DOUBLE) return sizeof(double);
-        return 0;
-    }
-
-    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 {
-            EnsureCapacity(PR_FALSE, count*ElementSize());
-            type = t;
-            length = count;
-            sizePerVertex = spv;
-        }
-    }
-
-    void Release() {
-        if (data)
-            PR_Free(data);
-        length = 0;
-        capacity = 0;
-        data = nsnull;
-    }
-
-    void EnsureCapacity(PRBool preserve, PRUint32 cap) {
-        if (capacity >= cap)
-            return;
-
-        void* newdata = PR_Malloc(cap);
-        if (preserve && length)
-            memcpy(newdata, data, length*ElementSize());
-        PR_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
-};
-
-
-class CanvasGLES11Texture :
-    public nsICanvasRenderingContextGLES11Texture
-{
-    friend class nsCanvasRenderingContextGLES11;
-public:
-    CanvasGLES11Texture(nsCanvasRenderingContextGLES11 *owner);
-    ~CanvasGLES11Texture();
-
-    NS_DECL_ISUPPORTS
-
-    NS_DECL_NSICANVASRENDERINGCONTEXTGLES11TEXTURE
-
-    nsresult Init();
-    nsresult Dispose();
-
-protected:
-    PRBool mDisposed;
-    nsCanvasRenderingContextGLES11 *mOwnerContext;
-
-    glitz_surface_t *mGlitzTextureSurface;
-    glitz_texture_object_t *mGlitzTextureObject;
-    PRUint32 mWidth;
-    PRUint32 mHeight;
-};
-
-#define CANVAS_GLES11_BUFFER_IID \
-    { 0x506a7b9b, 0x9159, 0x40ee, { 0x84, 0x63, 0xbe, 0x3f, 0x07, 0x3b, 0xc2, 0x32 } }
-
-// Private IID used for identifying an instance of this particular class
-const nsIID CanvasGLES11BufferIID = CANVAS_GLES11_BUFFER_IID;
-
-class CanvasGLES11Buffer :
-    public nsICanvasRenderingContextGLES11Buffer,
-    public nsISecurityCheckedComponent
-{
-    friend class nsCanvasRenderingContextGLES11;
-public:
-
-    CanvasGLES11Buffer(nsCanvasRenderingContextGLES11 *owner);
-    ~CanvasGLES11Buffer();
-
-    // Init can be called multiple times to reinitialize this
-    // buffer object
-    nsresult Init (PRUint32 usage,
-                   PRUint32 size,
-                   PRUint32 type,
-                   JSContext *ctx,
-                   JSObject *arrayObj,
-                   jsuint arrayLen);
-
-    SimpleBuffer& GetSimpleBuffer() { return mSimpleBuffer; }
-
-    NS_DECL_ISUPPORTS
-    NS_DECL_NSICANVASRENDERINGCONTEXTGLES11BUFFER
-    NS_DECL_NSISECURITYCHECKEDCOMPONENT
-
-protected:
-    CanvasGLES11Buffer() { }
-
-    inline GLEWContext *glewGetContext();
-
-    nsCanvasRenderingContextGLES11 *mOwnerContext;
-    PRBool mDisposed;
-
-    PRUint32 mLength;
-    PRUint32 mSize;
-    PRUint32 mType;
-    PRUint32 mUsage;
-
-    SimpleBuffer mSimpleBuffer;
-    GLuint mBufferID;
-};
-
 class nsCanvasRenderingContextGLES11 :
     public nsICanvasRenderingContextGLES11,
-    public nsICanvasRenderingContextInternal
+    public nsCanvasRenderingContextGLPrivate
 {
-    friend class CanvasGLES11Texture;
-    friend class CanvasGLES11Buffer;
 public:
     nsCanvasRenderingContextGLES11();
     virtual ~nsCanvasRenderingContextGLES11();
 
     NS_DECL_ISUPPORTS
 
+    NS_DECL_NSICANVASRENDERINGCONTEXTGL
+
     NS_DECL_NSICANVASRENDERINGCONTEXTGLES11
 
-    // nsICanvasRenderingContextInternal
-    NS_IMETHOD SetCanvasElement(nsICanvasElement* aParentCanvas);
-    NS_IMETHOD SetDimensions(PRInt32 width, PRInt32 height);
-    NS_IMETHOD Render(nsIRenderingContext *rc);
-    NS_IMETHOD RenderToSurface(cairo_surface_t *surf);
-    NS_IMETHOD GetInputStream(const nsACString& aMimeType,
-                              const nsAString& aEncoderOptions,
-                              nsIInputStream **aStream);
-
-    GLEWContext *glewGetContext() { return &mGlewContext; }
+    // nsICanvasRenderingContextPrivate
+    virtual nsICanvasRenderingContextGL *GetSelf() { return this; }
 
 protected:
-    nsIFrame *GetCanvasLayoutFrame();
-    inline void MakeContextCurrent();
-    static void LostCurrentContext(void *closure);
-
     inline PRBool CheckEnableMode(PRUint32 mode);
 
-    void Destroy();
-
-    static PRBool mGlitzInitialized;
-
-    PRPackedBool mCurrent;
-
-    PRInt32 mWidth, mHeight, mStride;
-    PRUint8 *mImageBuffer;
-
-    nsICanvasElement* mCanvasElement;
-
-    glitz_context_t* mGlitzContext;
-    glitz_drawable_t* mGlitzDrawable;
-    glitz_surface_t* mGlitzSurface;
-    glitz_buffer_t* mGlitzImageBuffer;
-
-    cairo_surface_t *mCairoImageSurface;
-
-    GLEWContext mGlewContext;
-    void *mContextToken;
-
-    static nsresult JSArrayToSimpleBuffer (SimpleBuffer& sbuffer, PRUint32 typeParam, PRUint32 sizeParam, JSContext *ctx, JSObject *arrayObj, jsuint arrayLen);
-
-    nsresult CairoSurfaceFromElement(nsIDOMElement *imgElt,
-                                     cairo_surface_t **aCairoSurface,
-                                     PRUint8 **imgData,
-                                     PRInt32 *widthOut, PRInt32 *heightOut,
-                                     nsIURI **uriOut, PRBool *forceWriteOnlyOut);
-    void DoDrawImageSecurityCheck(nsIURI* aURI, PRBool forceWriteOnly);
-
-    /* These are nsCOMPtrs because we'll be swapping them a lot, and
-     * don't want to have to worry about the ADDREF/RELEASE.  But
-     * we still want easy access to the CanvasGLES11Buffer* pointer,
-     * so there are some helper functions.
-     */
-    nsCOMPtr<nsICanvasRenderingContextGLES11Buffer> mVertexBuffer;
-    nsCOMPtr<nsICanvasRenderingContextGLES11Buffer> mNormalBuffer;
-    nsCOMPtr<nsICanvasRenderingContextGLES11Buffer> mColorBuffer;
-    nsCOMPtr<nsICanvasRenderingContextGLES11Buffer> mTexCoordBuffer[MAX_TEXTURE_UNITS];
-
-    CanvasGLES11Buffer* RealVertexBuffer() {
-        nsICanvasRenderingContextGLES11Buffer* ptr = mVertexBuffer.get();
-        return NS_STATIC_CAST(CanvasGLES11Buffer*, ptr);
-    }
-    CanvasGLES11Buffer* RealNormalBuffer() {
-        nsICanvasRenderingContextGLES11Buffer* ptr = mNormalBuffer.get();
-        return NS_STATIC_CAST(CanvasGLES11Buffer*, ptr);
-    }
-    CanvasGLES11Buffer* RealColorBuffer() {
-        nsICanvasRenderingContextGLES11Buffer* ptr = mColorBuffer.get();
-        return NS_STATIC_CAST(CanvasGLES11Buffer*, ptr);
-    }
-    CanvasGLES11Buffer* RealTexCoordBuffer(PRUint32 i) {
-        nsICanvasRenderingContextGLES11Buffer* ptr = mTexCoordBuffer[i].get();
-        return NS_STATIC_CAST(CanvasGLES11Buffer*, ptr);
-    }
+    nsRefPtr<CanvasGLBuffer> mVertexBuffer;
+    nsRefPtr<CanvasGLBuffer> mNormalBuffer;
+    nsRefPtr<CanvasGLBuffer> mColorBuffer;
+    nsRefPtr<CanvasGLBuffer> mTexCoordBuffer[MAX_TEXTURE_UNITS];
 
     PRPackedBool mVertexArrayEnabled;
     PRPackedBool mNormalArrayEnabled;
     PRPackedBool mColorArrayEnabled;
     PRPackedBool mTexCoordArrayEnabled[MAX_TEXTURE_UNITS];
 
     PRUint16 mActiveTextureUnit;
-
-#ifdef XP_WIN
-    HBITMAP mWinBitmap;
-    HDC mWinBitmapDC;
-#endif
-
-    static inline PRBool JSValToFloatArray (JSContext *ctx, jsval val,
-                                            jsuint cnt, float *array)
-    {
-        JSObject *arrayObj;
-        jsuint arrayLen;
-        jsval jv;
-        jsdouble dv;
-
-        if (!::JS_ValueToObject(ctx, val, &arrayObj) ||
-            !::JS_IsArrayObject(ctx, arrayObj) ||
-            !::JS_GetArrayLength(ctx, arrayObj, &arrayLen) ||
-            (arrayLen < cnt))
-            return PR_FALSE;
-
-        for (jsuint i = 0; i < cnt; i++) {
-            ::JS_GetElement(ctx, arrayObj, i, &jv);
-            if (!::JS_ValueToNumber(ctx, jv, &dv))
-                return PR_FALSE;
-            array[i] = (float) dv;
-        }
-
-        return PR_TRUE;
-    }
-
-    static inline PRBool JSValToDoubleArray (JSContext *ctx, jsval val,
-                                             jsuint cnt, double *array)
-    {
-        JSObject *arrayObj;
-        jsuint arrayLen;
-        jsval jv;
-        jsdouble dv;
-
-        if (!::JS_ValueToObject(ctx, val, &arrayObj) ||
-            !::JS_IsArrayObject(ctx, arrayObj) ||
-            !::JS_GetArrayLength(ctx, arrayObj, &arrayLen) ||
-            (arrayLen < cnt))
-            return PR_FALSE;
-
-        for (jsuint i = 0; i < cnt; i++) {
-            ::JS_GetElement(ctx, arrayObj, i, &jv);
-            if (!::JS_ValueToNumber(ctx, jv, &dv))
-                return PR_FALSE;
-            array[i] = dv;
-        }
-
-        return PR_TRUE;
-    }
-
-    static inline PRBool JSValToJSArrayAndLength (JSContext *ctx, jsval val,
-                                                  JSObject **outObj, jsuint *outLen)
-    {
-        JSObject *obj = nsnull;
-        jsuint len;
-        if (!::JS_ValueToObject(ctx, val, &obj) ||
-            !::JS_IsArrayObject(ctx, obj) ||
-            !::JS_GetArrayLength(ctx, obj, &len))
-        {
-            return PR_FALSE;
-        }
-
-        *outObj = obj;
-        *outLen = len;
-
-        return PR_TRUE;
-    }
 };
 
-PRBool nsCanvasRenderingContextGLES11::mGlitzInitialized = PR_FALSE;
-
 // let's all do the xpcom!
 
-// CanvasGLES11Buffer
-NS_DECL_CLASSINFO(CanvasGLES11Buffer)
-NS_IMPL_ADDREF(CanvasGLES11Buffer)
-NS_IMPL_RELEASE(CanvasGLES11Buffer)
-
-NS_IMPL_CI_INTERFACE_GETTER1(CanvasGLES11Buffer, nsICanvasRenderingContextGLES11Buffer)
-
-NS_INTERFACE_MAP_BEGIN(CanvasGLES11Buffer)
-  if (aIID.Equals(CanvasGLES11BufferIID))
-    foundInterface = NS_STATIC_CAST(nsICanvasRenderingContextGLES11Buffer*, this);
-  else
-  NS_INTERFACE_MAP_ENTRY(nsICanvasRenderingContextGLES11Buffer)
-  NS_INTERFACE_MAP_ENTRY(nsISecurityCheckedComponent)
-  NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsICanvasRenderingContextGLES11Buffer)
-  NS_IMPL_QUERY_CLASSINFO(CanvasGLES11Buffer)
-NS_INTERFACE_MAP_END
-
-// CanvasGLES11Texture
-NS_DECL_CLASSINFO(CanvasGLES11Texture)
-NS_IMPL_ADDREF(CanvasGLES11Texture)
-NS_IMPL_RELEASE(CanvasGLES11Texture)
-
-NS_IMPL_CI_INTERFACE_GETTER1(CanvasGLES11Texture, nsICanvasRenderingContextGLES11Texture)
-
-NS_INTERFACE_MAP_BEGIN(CanvasGLES11Texture)
-  NS_INTERFACE_MAP_ENTRY(nsICanvasRenderingContextGLES11Texture)
-  NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsICanvasRenderingContextGLES11Texture)
-  NS_IMPL_QUERY_CLASSINFO(CanvasGLES11Texture)
-NS_INTERFACE_MAP_END
-
 // nsCanvasRenderingContextGLES11
 // NS_DECL_CLASSINFO lives in nsCanvas3DModule
 NS_IMPL_ADDREF(nsCanvasRenderingContextGLES11)
 NS_IMPL_RELEASE(nsCanvasRenderingContextGLES11)
 
-NS_IMPL_CI_INTERFACE_GETTER2(nsCanvasRenderingContextGLES11,
+NS_IMPL_CI_INTERFACE_GETTER4(nsCanvasRenderingContextGLES11,
+                             nsICanvasRenderingContextGL,
                              nsICanvasRenderingContextGLES11,
-                             nsICanvasRenderingContextInternal)
+                             nsICanvasRenderingContextInternal,
+                             nsISupportsWeakReference)
 
 NS_INTERFACE_MAP_BEGIN(nsCanvasRenderingContextGLES11)
+  NS_INTERFACE_MAP_ENTRY(nsICanvasRenderingContextGL)
   NS_INTERFACE_MAP_ENTRY(nsICanvasRenderingContextGLES11)
   NS_INTERFACE_MAP_ENTRY(nsICanvasRenderingContextInternal)
-  NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsICanvasRenderingContextGLES11)
+  NS_INTERFACE_MAP_ENTRY(nsISupportsWeakReference)
+  NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsICanvasRenderingContextGL)
   NS_IMPL_QUERY_CLASSINFO(nsCanvasRenderingContextGLES11)
 NS_INTERFACE_MAP_END
 
 nsresult
 NS_NewCanvasRenderingContextGLES11(nsICanvasRenderingContextGLES11** aResult)
 {
     nsICanvasRenderingContextGLES11* ctx = new nsCanvasRenderingContextGLES11();
     if (!ctx)
         return NS_ERROR_OUT_OF_MEMORY;
 
+    fprintf (stderr, "VVVVV NS_New called\n"); fflush(stderr);
     NS_ADDREF(*aResult = ctx);
     return NS_OK;
 }
 
 nsCanvasRenderingContextGLES11::nsCanvasRenderingContextGLES11()
-    : mCurrent(PR_FALSE),
-      mWidth(0), mHeight(0), mStride(0), mImageBuffer(nsnull),
-      mCanvasElement(nsnull),
-      mGlitzContext(nsnull), mGlitzDrawable(nsnull), mGlitzSurface(nsnull), mGlitzImageBuffer(nsnull),
-      mCairoImageSurface(nsnull),
-      mVertexArrayEnabled(PR_FALSE),
+    : mVertexArrayEnabled(PR_FALSE),
       mNormalArrayEnabled(PR_FALSE),
       mColorArrayEnabled(PR_FALSE),
-      mActiveTextureUnit(0),
-      mContextToken(nsnull)
+      mActiveTextureUnit(0)
 {
 #ifdef PR_LOGGING
     if (!gGLES11Log)
         gGLES11Log = PR_NewLogModule("canvasGLES11");
 #endif
 
     PR_LOG(gGLES11Log, PR_LOG_DEBUG, ("##[%p] Creating GLES11 canvas context\n", this));
 
-    if (!mGlitzInitialized) {
-#ifdef MOZ_X11
-        glitz_glx_init("libGL.so.1");
-#endif
-#ifdef XP_WIN
-        glitz_wgl_init(NULL);
-#endif
-        mGlitzInitialized = PR_TRUE;
-    }
-
     for (int i = 0; i < MAX_TEXTURE_UNITS; i++)
         mTexCoordArrayEnabled[i] = PR_FALSE;
-
-    // grab the xpconnect service
-    if (!gXPConnect) {
-        nsresult rv = CallGetService(nsIXPConnect::GetCID(), &gXPConnect);
-        if (NS_FAILED(rv)) {
-            NS_ERROR("Failed to get XPConnect!");
-            return;
-        }
-    } else {
-        NS_ADDREF(gXPConnect);
-    }
-
-    if (!gJSRuntimeService) {
-        nsresult rv = CallGetService("@mozilla.org/js/xpc/RuntimeService;1",
-                                     &gJSRuntimeService);
-        if (NS_FAILED(rv)) {
-            // uh..
-            NS_ERROR("Failed to get JS RuntimeService!");
-            return;
-        }
-
-        gJSRuntimeService->GetRuntime(&gScriptRuntime);
-        if (!gScriptRuntime) {
-            NS_RELEASE(gJSRuntimeService);
-            gJSRuntimeService = nsnull;
-            NS_ERROR("Unable to get JS runtime from JS runtime service");
-        }
-    } else {
-        NS_ADDREF(gJSRuntimeService);
-    }
-
-#ifdef XP_WIN
-    mWinBitmap = nsnull;
-    mWinBitmapDC = nsnull;
-#endif
 }
 
 nsCanvasRenderingContextGLES11::~nsCanvasRenderingContextGLES11()
 {
-    Destroy();
-    if (gXPConnect && gXPConnect->Release() == 0)
-        gXPConnect = nsnull;
-    if (gJSRuntimeService && gJSRuntimeService->Release() == 0) {
-        gJSRuntimeService = nsnull;
-        gScriptRuntime = nsnull;
-    }
-}
-
-void
-nsCanvasRenderingContextGLES11::Destroy()
-{
-    PR_LOG(gGLES11Log, PR_LOG_DEBUG, ("##[%p] Destroying GLES11 canvas context\n", this));
-
-    if (mCairoImageSurface) {
-        cairo_surface_destroy (mCairoImageSurface);
-        mCairoImageSurface = nsnull;
-    }
-
-    if (mGlitzImageBuffer) {
-        glitz_buffer_destroy(mGlitzImageBuffer);
-        mGlitzImageBuffer = nsnull;
-    }
-
-    if (mGlitzContext) {
-        glitz_context_destroy (mGlitzContext);
-        mGlitzContext = nsnull;
-    }
-    if (mGlitzSurface) {
-        glitz_surface_destroy (mGlitzSurface);
-        mGlitzSurface = nsnull;
-    }
-
-    // XXX bad memlk; but we already destroyed the context,
-    // so when this tries to free the fragment shaders,
-    // it tries to activate the context, and that blows up. wtf?!
-    if (mGlitzDrawable) {
-        glitz_drawable_destroy (mGlitzDrawable);
-        mGlitzDrawable = nsnull;
-    }
-
-#ifdef XP_WIN
-    if (mWinBitmapDC) {
-        DeleteDC(mWinBitmapDC);
-        mWinBitmapDC = nsnull;
-    }
-
-    if (mWinBitmap) {
-        DeleteObject(mWinBitmap);
-        mWinBitmap = nsnull;
-        mImageBuffer = nsnull;
-    }
-#endif
-
-    if (mImageBuffer) {
-        PR_Free(mImageBuffer);
-        mImageBuffer = nsnull;
-    }
-}
-
-void
-nsCanvasRenderingContextGLES11::MakeContextCurrent()
-{
-#ifdef XP_WIN
-    if (mContextToken == nsnull) {
-        glitz_context_make_current (mGlitzContext, mGlitzDrawable);
-        mContextToken = wglGetCurrentContext();
-        mCurrent = PR_TRUE;
-        return;
-    }
-
-    if (mContextToken != wglGetCurrentContext()) {
-        glitz_context_make_current (mGlitzContext, mGlitzDrawable);
-        mCurrent = PR_TRUE;
-    }
-#endif
-
-#if 0
-    if (!mCurrent) {
-        fprintf (stderr, "[this:%p] Making context %p current (current: %d)\n", this, mGlitzContext, mCurrent);
-        fflush (stderr);
-        glitz_context_set_user_data (mGlitzContext, this, LostCurrentContext);
-    }
-#endif
-}
-
-void
-nsCanvasRenderingContextGLES11::LostCurrentContext(void *closure)
-{
-    nsCanvasRenderingContextGLES11* self = (nsCanvasRenderingContextGLES11*) closure;
-    fprintf (stderr, "[this:%p] Lost context\n", closure);
-    fflush (stderr);
-
-    self->mCurrent = PR_FALSE;
-}
-
-//
-// nsICanvasRenderingContextInternal
-//
-
-NS_IMETHODIMP
-nsCanvasRenderingContextGLES11::SetCanvasElement(nsICanvasElement* aParentCanvas)
-{
-    mCanvasElement = aParentCanvas;
-    fprintf (stderr, "SetCanvasElement: %p\n", mCanvasElement);
-    return NS_OK;
-}
-
-NS_IMETHODIMP
-nsCanvasRenderingContextGLES11::SetDimensions(PRInt32 width, PRInt32 height)
-{
-    fprintf (stderr, "SetDimensions\n");
-    if (mWidth == width && mHeight == height)
-        return NS_OK;
-
-    Destroy();
-
-    PR_LOG(gGLES11Log, PR_LOG_DEBUG, ("##[%p] SetDimensions: %d %d\n", this, width, height));
-
-    glitz_drawable_format_t *gdformat = nsnull;
-
-#ifdef MOZ_X11
-    Display* display = GDK_DISPLAY();
-
-    glitz_drawable_format_t templ;
-    templ.color.fourcc = GLITZ_FOURCC_RGB;
-    templ.color.red_size = 8;
-    templ.color.green_size = 8;
-    templ.color.blue_size = 8;
-    templ.color.alpha_size = 8;
-    templ.doublebuffer = 0;
-    
-    gdformat = glitz_glx_find_pbuffer_format
-        (display,
-         gdk_x11_get_default_screen(),
-         GLITZ_FORMAT_FOURCC_MASK |
-         GLITZ_FORMAT_RED_SIZE_MASK | GLITZ_FORMAT_GREEN_SIZE_MASK |
-         GLITZ_FORMAT_BLUE_SIZE_MASK | GLITZ_FORMAT_ALPHA_SIZE_MASK |
-         GLITZ_FORMAT_DOUBLEBUFFER_MASK, &templ, 0);
-
-    if (!gdformat)
-        return NS_ERROR_INVALID_ARG;
-
-    mGlitzDrawable =
-        glitz_glx_create_pbuffer_drawable(display,
-                                          DefaultScreen(display),
-                                          gdformat,
-                                          width,
-                                          height);
-#endif
-
-#ifdef XP_WIN
-    glitz_drawable_format_t templ;
-    templ.color.fourcc = GLITZ_FOURCC_RGB;
-    templ.color.red_size = 8;
-    templ.color.green_size = 8;
-    templ.color.blue_size = 8;
-    templ.color.alpha_size = 8;
-    templ.doublebuffer = 0;
-    templ.samples = 8;
-
-    gdformat = nsnull;
-
-    do {
-        templ.samples = templ.samples >> 1;
-        gdformat = glitz_wgl_find_pbuffer_format
-            (GLITZ_FORMAT_FOURCC_MASK |
-             GLITZ_FORMAT_RED_SIZE_MASK | GLITZ_FORMAT_GREEN_SIZE_MASK |
-             GLITZ_FORMAT_BLUE_SIZE_MASK | GLITZ_FORMAT_ALPHA_SIZE_MASK |
-             GLITZ_FORMAT_DOUBLEBUFFER_MASK | GLITZ_FORMAT_SAMPLES_MASK,
-             &templ, 0);
-    } while (gdformat == nsnull && templ.samples > 0);
-
-    if (!gdformat)
-        return NS_ERROR_INVALID_ARG;
-
-    mGlitzDrawable =
-        glitz_wgl_create_pbuffer_drawable(gdformat,
-                                          width,
-                                          height);
-#endif
-
-    if (!gdformat || !mGlitzDrawable)
-        return NS_ERROR_FAILURE;
-
-    glitz_format_t *gformat =
-        glitz_find_standard_format(mGlitzDrawable, GLITZ_STANDARD_ARGB32);
-    if (!gformat)
-        return NS_ERROR_INVALID_ARG;
-
-    mGlitzSurface =
-        glitz_surface_create(mGlitzDrawable,
-                             gformat,
-                             width,
-                             height,
-                             0,
-                             NULL);
-    if (!mGlitzSurface)
-        return NS_ERROR_INVALID_ARG;
-
-    glitz_surface_attach(mGlitzSurface, mGlitzDrawable, GLITZ_DRAWABLE_BUFFER_FRONT_COLOR);
-
-    mGlitzContext = glitz_context_create (mGlitzDrawable, gdformat);
-
-    MakeContextCurrent();
-
-    GLenum err = glewInit();
-    if (err != GLEW_OK) {
-        // er, something very bad happened
-        NS_ERROR("glewInit failed!  Leaking lots of memory");
-        return NS_ERROR_FAILURE;
-    }
-
-    //mSurface = new gfxGlitzSurface (mGlitzDrawable, gsurf, PR_TRUE);
-    mWidth = width;
-    mHeight = height;
-
-    mStride = (((mWidth*4) + 3) / 4) * 4;
-
-#ifdef XP_WIN
-    BITMAPINFO *bitmap_info = (BITMAPINFO*) PR_Malloc(sizeof(BITMAPINFOHEADER));
-    bitmap_info->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
-    bitmap_info->bmiHeader.biWidth = mWidth;
-    bitmap_info->bmiHeader.biHeight = mHeight;
-    bitmap_info->bmiHeader.biSizeImage = 0;
-    bitmap_info->bmiHeader.biXPelsPerMeter = 2834; /* unused here */
-    bitmap_info->bmiHeader.biYPelsPerMeter = 2834; /* unused here */
-    bitmap_info->bmiHeader.biPlanes = 1;
-    bitmap_info->bmiHeader.biBitCount = 32;
-    bitmap_info->bmiHeader.biCompression = BI_RGB;
-    bitmap_info->bmiHeader.biClrUsed = 0;	/* unused */
-    bitmap_info->bmiHeader.biClrImportant = 0;
+    // we need to make sure that everything is destroyed/nulled out,
+    // because we won't have a context when destructors finish; destroying
+    // some of these may need to call glDeleteBuffers.
+    mVertexBuffer = nsnull;
+    mNormalBuffer = nsnull;
+    mColorBuffer = nsnull;
+    for (int i = 0; i < MAX_TEXTURE_UNITS; i++)
+        mTexCoordBuffer[i] = nsnull;
 
-    mWinBitmapDC = CreateCompatibleDC(NULL);
-    if (mWinBitmapDC) {
-        void *bits = nsnull;
-        mWinBitmap = CreateDIBSection (mWinBitmapDC,
-                                       bitmap_info,
-                                       DIB_RGB_COLORS,
-                                       &bits,
-                                       NULL, 0);
-        if (mWinBitmap) {
-            SelectObject (mWinBitmapDC, mWinBitmap);
-            GdiFlush();
-
-            mImageBuffer = (PRUint8*) bits;
-            mCairoImageSurface = cairo_win32_surface_create (mWinBitmapDC);
-#ifdef MOZILLA_1_8_BRANCH
-            ((struct _cairo_surface_win32_hack*)mCairoImageSurface)->format = CAIRO_FORMAT_ARGB32;
-#endif
-        } else {
-            DeleteDC(mWinBitmapDC);
-        }
-    }
-
-    PR_Free(bitmap_info);
-#endif
-
-    if (!mImageBuffer) {
-        mImageBuffer = (PRUint8*) PR_Malloc(mStride * mHeight);
-        if (mImageBuffer) {
-            mCairoImageSurface = cairo_image_surface_create_for_data (mImageBuffer,
-                                                                      CAIRO_FORMAT_ARGB32,
-                                                                      mWidth,
-                                                                      mHeight,
-                                                                      mStride);
-        }
-    }
-
-    if (!mImageBuffer)
-        return NS_ERROR_FAILURE;
-
-    mGlitzImageBuffer = glitz_buffer_create_for_data (mImageBuffer);
-
-    return NS_OK;
-}
-
-/*
- * This is identical to nsCanvasRenderingContext2D::Render, we just don't
- * have a good place to put it; though maybe I want a CanvasContextImpl that
- * all this stuff can derive from?
- */
-NS_IMETHODIMP
-nsCanvasRenderingContextGLES11::Render(nsIRenderingContext *rc)
-{
-    nsresult rv = NS_OK;
-
-    if (!mImageBuffer)
-        return NS_OK;
-
-#ifdef MOZ_CAIRO_GFX
-
-    gfxContext* ctx = (gfxContext*) rc->GetNativeGraphicData(nsIRenderingContext::NATIVE_THEBES_CONTEXT);
-    nsRefPtr<gfxASurface> surf = gfxASurface::Wrap(mCairoImageSurface);
-    nsRefPtr<gfxPattern> pat = new gfxPattern(surf);
-
-    // XXX I don't want to use PixelSnapped here, but layout doesn't guarantee
-    // pixel alignment for this stuff!
-    ctx->NewPath();
-    ctx->PixelSnappedRectangleAndSetPattern(gfxRect(0, 0, mWidth, mHeight), pat);
-    ctx->Fill();
-
-#else
-
-    // non-Thebes; this becomes exciting
-    cairo_surface_t *dest = nsnull;
-    cairo_t *dest_cr = nsnull;
-
-#ifdef XP_WIN
-    void *ptr = nsnull;
-#ifdef MOZILLA_1_8_BRANCH
-    rv = rc->RetrieveCurrentNativeGraphicData(&ptr);
-    if (NS_FAILED(rv) || !ptr)
-        return NS_ERROR_FAILURE;
-#else
-    ptr = rc->GetNativeGraphicData(nsIRenderingContext::NATIVE_WINDOWS_DC);
-#endif
-    HDC dc = (HDC) ptr;
-
-    dest = cairo_win32_surface_create (dc);
-    dest_cr = cairo_create (dest);
-#endif
-
-#ifdef MOZ_WIDGET_GTK2
-    GdkDrawable *gdkdraw = nsnull;
-#ifdef MOZILLA_1_8_BRANCH
-    rv = rc->RetrieveCurrentNativeGraphicData((void**) &gdkdraw);
-    if (NS_FAILED(rv) || !gdkdraw)
-        return NS_ERROR_FAILURE;
-#else
-    gdkdraw = (GdkDrawable*) rc->GetNativeGraphicData(nsIRenderingContext::NATIVE_GDK_DRAWABLE);
-    if (!gdkdraw)
-        return NS_ERROR_FAILURE;
-#endif
-
-    gint w, h;
-    gdk_drawable_get_size (gdkdraw, &w, &h);
-    dest = cairo_xlib_surface_create (GDK_DRAWABLE_XDISPLAY(gdkdraw),
-                                      GDK_DRAWABLE_XID(gdkdraw),
-                                      GDK_VISUAL_XVISUAL(gdk_drawable_get_visual(gdkdraw)),
-                                      w, h);
-    dest_cr = cairo_create (dest);
-#endif
-
-    nsTransform2D *tx = nsnull;
-    rc->GetCurrentTransform(tx);
-
-    nsCOMPtr<nsIDeviceContext> dctx;
-    rc->GetDeviceContext(*getter_AddRefs(dctx));
-
-    // Until we can use the quartz2 surface, mac will be different,
-    // since we'll use CG to render.
-#ifndef XP_MACOSX
-
-    float x0 = 0.0, y0 = 0.0;
-    float sx = 1.0, sy = 1.0;
-    if (tx->GetType() & MG_2DTRANSLATION) {
-        tx->Transform(&x0, &y0);
-    }
-
-    if (tx->GetType() & MG_2DSCALE) {
-        sx = sy = dctx->DevUnitsToTwips();
-        tx->TransformNoXLate(&sx, &sy);
-    }
-
-    cairo_translate (dest_cr, NSToIntRound(x0), NSToIntRound(y0));
-    if (sx != 1.0 || sy != 1.0)
-        cairo_scale (dest_cr, sx, sy);
-
-    cairo_rectangle (dest_cr, 0, 0, mWidth, mHeight);
-    cairo_clip (dest_cr);
-
-    cairo_set_source_surface (dest_cr, mCairoImageSurface, 0, 0);
-    cairo_paint (dest_cr);
-
-    if (dest_cr)
-        cairo_destroy (dest_cr);
-    if (dest)
-        cairo_surface_destroy (dest);
-
-#else
-
-    // OSX path
-
-    CGrafPtr port = nsnull;
-#ifdef MOZILLA_1_8_BRANCH
-    rv = rc->RetrieveCurrentNativeGraphicData((void**) &port);
-    if (NS_FAILED(rv) || !port)
-        return NS_ERROR_FAILURE;
-#else
-    port = (CGrafPtr) rc->GetNativeGraphicData(nsIRenderingContext::NATIVE_MAC_THING);
-    if (!port)
-        return NS_ERROR_FAILURE;
-#endif
-
-    struct Rect portRect;
-    GetPortBounds(port, &portRect);
-
-    CGContextRef cgc;
-    OSStatus status;
-    status = QDBeginCGContext (port, &cgc);
-    if (status != noErr)
-        return NS_ERROR_FAILURE;
-
-    CGDataProviderRef dataProvider;
-    CGImageRef img;
-
-    dataProvider = CGDataProviderCreateWithData (NULL, mImageBuffer,
-                                                 mWidth * mHeight * 4,
-                                                 NULL);
-    CGColorSpaceRef rgb = CGColorSpaceCreateDeviceRGB();
-    img = CGImageCreate (mWidth, mHeight, 8, 32, mWidth * 4, rgb,
-                         kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Host,
-                         dataProvider, NULL, false, kCGRenderingIntentDefault);
-    CGColorSpaceRelease (rgb);
-    CGDataProviderRelease (dataProvider);
-
-    float x0 = 0.0, y0 = 0.0;
-    float sx = 1.0, sy = 1.0;
-    if (tx->GetType() & MG_2DTRANSLATION) {
-        tx->Transform(&x0, &y0);
-    }
-
-    if (tx->GetType() & MG_2DSCALE) {
-        float p2t = dctx->DevUnitsToTwips();
-        sx = p2t, sy = p2t;
-        tx->TransformNoXLate(&sx, &sy);
-    }
-
-    /* Compensate for the bottom-left Y origin */
-    CGContextTranslateCTM (cgc, NSToIntRound(x0),
-                           portRect.bottom - portRect.top - NSToIntRound(y0) - NSToIntRound(mHeight * sy));
-    if (sx != 1.0 || sy != 1.0)
-        CGContextScaleCTM (cgc, sx, sy);
-
-    CGContextDrawImage (cgc, CGRectMake(0, 0, mWidth, mHeight), img);
-
-    CGImageRelease (img);
-
-    status = QDEndCGContext (port, &cgc);
-    /* if EndCGContext fails, what can we do? */
-#endif
-#endif
-
-    return rv;
-}
-
-NS_IMETHODIMP
-nsCanvasRenderingContextGLES11::RenderToSurface(cairo_surface_t *surf)
-{
-    return NS_OK;
-}
-
-nsIFrame*
-nsCanvasRenderingContextGLES11::GetCanvasLayoutFrame()
-{
-    if (!mCanvasElement)
-        return nsnull;
-
-    nsIFrame *fr = nsnull;
-    mCanvasElement->GetPrimaryCanvasFrame(&fr);
-    return fr;
-}
-
-NS_IMETHODIMP
-nsCanvasRenderingContextGLES11::GetInputStream(const nsACString& aMimeType,
-                                               const nsAString& aEncoderOptions,
-                                               nsIInputStream **aStream)
-{
-    return NS_ERROR_NOT_IMPLEMENTED;
+    fprintf (stderr, "VVVVV ~nsCanvasRenderingContextGLES11\n");
+    fflush (stderr);
 }
 
 //
 // Windowing system lookalike functions
 //
 
 NS_IMETHODIMP
 nsCanvasRenderingContextGLES11::SwapBuffers()
 {
-    if (!mImageBuffer)
-        return NS_OK;
-
-    MakeContextCurrent();
-
-    // call glitz_get_pixels to pull out the pixels
-    glitz_pixel_format_t argb_pf =
-        { GLITZ_FOURCC_RGB,
-          { 32, 0xff000000, 0x00ff0000, 0x0000ff00, 0x000000ff },
-          0,
-          0,
-          mStride,
-          GLITZ_PIXEL_SCANLINE_ORDER_TOP_DOWN
-        };
-
-    glitz_pixel_format_t *pf = &argb_pf;
-
-    glitz_get_pixels (mGlitzSurface,
-                      0, 0, mWidth, mHeight, pf, mGlitzImageBuffer);
-
-    // then invalidate the region and do a sync redraw
-    // (uh, why sync?)
-    nsIFrame *frame = GetCanvasLayoutFrame();
-    if (frame) {
-        nsRect r = frame->GetRect();
-        r.x = r.y = 0;
-
-        // sync redraw
-        //frame->Invalidate(r, PR_TRUE);
-
-        // nsIFrame::Invalidate is an internal non-virtual method,
-        // so we basically recreate it here.  I would suggest
-        // an InvalidateExternal for the trunk.
-        nsIPresShell *shell = frame->GetPresContext()->GetPresShell();
-        if (shell) {
-            PRBool suppressed = PR_FALSE;
-            shell->IsPaintingSuppressed(&suppressed);
-            if (suppressed)
-                return NS_OK;
-        }
-
-        // maybe VMREFRESH_IMMEDIATE in some cases,
-        // need to think
-        PRUint32 flags = NS_VMREFRESH_NO_SYNC;
-        if (frame->HasView()) {
-            nsIView* view = frame->GetViewExternal();
-            view->GetViewManager()->UpdateView(view, r, flags);
-        } else {
-            nsPoint offset;
-            nsIView *view;
-            frame->GetOffsetFromView(offset, &view);
-            NS_ASSERTION(view, "no view");
-            r += offset;
-            view->GetViewManager()->UpdateView(view, r, flags);
-        }
-    }
-
-    return NS_OK;
-}
-
-/* Helper macros for when we're just wrapping a gl method, so that
- * we can avoid having to type this 500 times.  Note that these MUST
- * NOT BE USED if we need to check any of the parameters.
- */
-
-#define GL_SAME_METHOD_0(glname, name)                       \
-NS_IMETHODIMP nsCanvasRenderingContextGLES11::name() {       \
-    MakeContextCurrent(); gl##glname(); return NS_OK;        \
-}
-
-#define GL_SAME_METHOD_1(glname, name, t1)                            \
-NS_IMETHODIMP nsCanvasRenderingContextGLES11::name(t1 a1) {           \
-    MakeContextCurrent(); gl##glname(a1); return NS_OK;               \
-}
-
-#define GL_SAME_METHOD_2(glname, name, t1, t2)                          \
-NS_IMETHODIMP nsCanvasRenderingContextGLES11::name(t1 a1, t2 a2) {      \
-    MakeContextCurrent(); gl##glname(a1,a2); return NS_OK;              \
-}
-
-#define GL_SAME_METHOD_3(glname, name, t1, t2, t3)                        \
-NS_IMETHODIMP nsCanvasRenderingContextGLES11::name(t1 a1, t2 a2, t3 a3) { \
-    MakeContextCurrent(); gl##glname(a1,a2,a3); return NS_OK;             \
-}
-
-#define GL_SAME_METHOD_4(glname, name, t1, t2, t3, t4)                           \
-NS_IMETHODIMP nsCanvasRenderingContextGLES11::name(t1 a1, t2 a2, t3 a3, t4 a4) { \
-    MakeContextCurrent(); gl##glname(a1,a2,a3,a4); return NS_OK;                 \
-}
-
-#define GL_SAME_METHOD_5(glname, name, t1, t2, t3, t4, t5)                              \
-NS_IMETHODIMP nsCanvasRenderingContextGLES11::name(t1 a1, t2 a2, t3 a3, t4 a4, t5 a5) { \
-    MakeContextCurrent(); gl##glname(a1,a2,a3,a4,a5); return NS_OK;                     \
-}
-
-#define GL_SAME_METHOD_6(glname, name, t1, t2, t3, t4, t5, t6)                                 \
-NS_IMETHODIMP nsCanvasRenderingContextGLES11::name(t1 a1, t2 a2, t3 a3, t4 a4, t5 a5, t6 a6) { \
-    MakeContextCurrent(); gl##glname(a1,a2,a3,a4,a5,a6); return NS_OK;                         \
-}
-
-
-nsresult
-nsCanvasRenderingContextGLES11::JSArrayToSimpleBuffer (SimpleBuffer& sbuffer, PRUint32 typeParam, PRUint32 sizeParam, JSContext *ctx, JSObject *arrayObj, jsuint arrayLen)
-{
-    sbuffer.Prepare(typeParam, sizeParam, arrayLen);
-
-    if (typeParam == GL_SHORT) {
-        short *ptr = (short*) sbuffer.data;
-        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 == GL_FLOAT) {
-        float *ptr = (float*) sbuffer.data;
-        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;
-        }
-    } else if (typeParam == GL_UNSIGNED_BYTE) {
-        unsigned char *ptr = (unsigned char*) sbuffer.data;
-        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 == GL_UNSIGNED_INT) {
-        PRUint32 *ptr = (PRUint32*) sbuffer.data;
-        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 {
-        return NS_ERROR_NOT_IMPLEMENTED;
-    }
-
-    return NS_OK;
+    return DoSwapBuffers();
 }
 
 //
 // nsICanvasRenderingContextGLES11
 //
 
 NS_IMETHODIMP
 nsCanvasRenderingContextGLES11::GetCanvas(nsIDOMHTMLCanvasElement **_retval)
@@ -1441,55 +439,42 @@ nsCanvasRenderingContextGLES11::MultiTex
 
     return NS_OK;
 }
 
 /* void color (in float r, in float g, in float b, in float a); */
 GL_SAME_METHOD_4(Color4f, Color, float, float, float, float)
 
 /* void vertexPointer (in PRUint8 size, in PRUint32 type, in object [] vertexArray); */
-/* void vertexPointer (in CanvasGLES11Buffer buffer); */
+/* void vertexPointer (in CanvasGLBuffer buffer); */
 NS_IMETHODIMP
 nsCanvasRenderingContextGLES11::VertexPointer()
 {
+    {
     NativeJSContext js;
     if (NS_FAILED(js.error))
         return js.error;
 
-    CanvasGLES11Buffer *newBuffer = nsnull;
+    nsRefPtr<CanvasGLBuffer> newBuffer;
     nsresult rv;
 
     if (js.argc == 1) {
-        if (!JSVAL_IS_OBJECT(js.argv[0]) ||
-            JSVAL_IS_NULL(js.argv[0]))
-            return NS_ERROR_DOM_SYNTAX_ERR;
-
-        nsCOMPtr<nsISupports> iface;
-        rv = gXPConnect->WrapJS(js.ctx, JSVAL_TO_OBJECT(js.argv[0]),
-                                NS_GET_IID(nsICanvasRenderingContextGLES11Buffer),
-                                getter_AddRefs(iface));
+        nsCOMPtr<nsICanvasRenderingContextGLBuffer> bufferBase;
+        rv = JSValToSpecificInterface(js.ctx, js.argv[0], (nsICanvasRenderingContextGLBuffer**) getter_AddRefs(bufferBase));
         if (NS_FAILED(rv))
-            return NS_ERROR_DOM_SYNTAX_ERR;
+            return rv;
 
-        // what we want is a CanvasGLES11Buffer; QI to our magic IID
-        // will return this interface
-        nsICanvasRenderingContextGLES11Buffer *bufferBase = nsnull;
-        rv = iface->QueryInterface(CanvasGLES11BufferIID, (void **) &bufferBase);
-        if (NS_FAILED(rv) || !bufferBase)
-            return NS_ERROR_FAILURE;
-
-        newBuffer = NS_STATIC_CAST(CanvasGLES11Buffer*, bufferBase);
+        newBuffer = (CanvasGLBuffer*) bufferBase.get();
 
         if (newBuffer->mType != GL_SHORT &&
             newBuffer->mType != GL_FLOAT)
             return NS_ERROR_DOM_SYNTAX_ERR;
 
         if (newBuffer->mSize < 2 || newBuffer->mSize > 4)
             return NS_ERROR_DOM_SYNTAX_ERR;
-
     } else if (js.argc == 3) {
         jsuint sizeParam;
         jsuint typeParam;
 
         JSObject *arrayObj;
         jsuint arrayLen;
 
         if (!::JS_ValueToECMAUint32(js.ctx, js.argv[0], &sizeParam) ||
@@ -1499,70 +484,63 @@ nsCanvasRenderingContextGLES11::VertexPo
             return NS_ERROR_DOM_SYNTAX_ERR;
         }
 
         if (typeParam != GL_SHORT &&
             typeParam != GL_FLOAT &&
             (sizeParam < 2 || sizeParam > 4))
             return NS_ERROR_DOM_SYNTAX_ERR;
 
-        newBuffer = new CanvasGLES11Buffer(this);
+        newBuffer = new CanvasGLBuffer(this);
         if (!newBuffer)
             return NS_ERROR_OUT_OF_MEMORY;
 
         rv = newBuffer->Init (GL_STATIC_DRAW, sizeParam, typeParam, js.ctx, arrayObj, arrayLen);
-        if (NS_FAILED(rv)) {
-            delete newBuffer;
+        if (NS_FAILED(rv))
             return rv;
-        }
+
     } else {
         return NS_ERROR_DOM_SYNTAX_ERR;
     }
 
     mVertexBuffer = newBuffer;
 
     MakeContextCurrent();
     glVertexPointer(newBuffer->GetSimpleBuffer().sizePerVertex,
                     newBuffer->GetSimpleBuffer().type,
                     0,
                     newBuffer->GetSimpleBuffer().data);
+
+}
+    (mVertexBuffer.get())->AddRef();
+    nsrefcnt kk = (mVertexBuffer.get())->Release();
+    fprintf (stderr, "VVVVV After VertexPointer: mVertexBuffer: %p refcount: %d\n", mVertexBuffer, kk);
+    fflush(stderr);
+
     return NS_OK;
 }
 
 /* void normalPointer (); */
 NS_IMETHODIMP
 nsCanvasRenderingContextGLES11::NormalPointer()
 {
     NativeJSContext js;
     if (NS_FAILED(js.error))
         return js.error;
 
-    CanvasGLES11Buffer *newBuffer = nsnull;
+    nsRefPtr<CanvasGLBuffer> newBuffer;
     nsresult rv;
 
     if (js.argc == 1) {
-        if (!JSVAL_IS_OBJECT(js.argv[0]) ||
-            JSVAL_IS_NULL(js.argv[0]))
-            return NS_ERROR_DOM_SYNTAX_ERR;
-
-        nsCOMPtr<nsISupports> iface;
-        rv = gXPConnect->WrapJS(js.ctx, JSVAL_TO_OBJECT(js.argv[0]),
-                                NS_GET_IID(nsICanvasRenderingContextGLES11Buffer),
-                                getter_AddRefs(iface));
+        nsCOMPtr<nsICanvasRenderingContextGLBuffer> bufferBase;
+        rv = JSValToSpecificInterface(js.ctx, js.argv[0], (nsICanvasRenderingContextGLBuffer**) getter_AddRefs(bufferBase));
         if (NS_FAILED(rv))
-            return NS_ERROR_DOM_SYNTAX_ERR;
+            return rv;
 
-        // what we want is a CanvasGLES11Buffer; QI to our magic IID
-        // will return this interface
-        nsICanvasRenderingContextGLES11Buffer *bufferBase = nsnull;
-        rv = iface->QueryInterface(CanvasGLES11BufferIID, (void **) &bufferBase);
-        if (NS_FAILED(rv) || !bufferBase)
-            return NS_ERROR_FAILURE;
-
-        newBuffer = NS_STATIC_CAST(CanvasGLES11Buffer*, bufferBase);
+        newBuffer = (CanvasGLBuffer*) bufferBase.get();
 
         if (newBuffer->mType != GL_SHORT &&
             newBuffer->mType != GL_FLOAT)
             return NS_ERROR_DOM_SYNTAX_ERR;
 
         if (newBuffer->mSize != 3)
             return NS_ERROR_DOM_SYNTAX_ERR;
     } else if (js.argc == 2) {
@@ -1575,25 +553,23 @@ nsCanvasRenderingContextGLES11::NormalPo
             !JSValToJSArrayAndLength(js.ctx, js.argv[1], &arrayObj, &arrayLen))
         {
             return NS_ERROR_DOM_SYNTAX_ERR;
         }
 
         if (typeParam != GL_SHORT && typeParam != GL_FLOAT)
             return NS_ERROR_DOM_SYNTAX_ERR;
 
-        newBuffer = new CanvasGLES11Buffer(this);
+        newBuffer = new CanvasGLBuffer(this);
         if (!newBuffer)
             return NS_ERROR_OUT_OF_MEMORY;
 
         rv = newBuffer->Init (GL_STATIC_DRAW, 3, typeParam, js.ctx, arrayObj, arrayLen);
-        if (NS_FAILED(rv)) {
-            delete newBuffer;
+        if (NS_FAILED(rv))
             return NS_ERROR_DOM_SYNTAX_ERR;
-        }
     } else {
         return NS_ERROR_DOM_SYNTAX_ERR;
     }
 
     mNormalBuffer = newBuffer;
 
     MakeContextCurrent();
     glNormalPointer(newBuffer->GetSimpleBuffer().type,
@@ -1606,39 +582,26 @@ nsCanvasRenderingContextGLES11::NormalPo
 /* void texCoordPointer (); */
 NS_IMETHODIMP
 nsCanvasRenderingContextGLES11::TexCoordPointer()
 {
     NativeJSContext js;
     if (NS_FAILED(js.error))
         return js.error;
 
-    CanvasGLES11Buffer *newBuffer = nsnull;
+    nsRefPtr<CanvasGLBuffer> newBuffer;
     nsresult rv;
 
     if (js.argc == 1) {
-        if (!JSVAL_IS_OBJECT(js.argv[0]) ||
-            JSVAL_IS_NULL(js.argv[0]))
-            return NS_ERROR_DOM_SYNTAX_ERR;
-
-        nsCOMPtr<nsISupports> iface;
-        rv = gXPConnect->WrapJS(js.ctx, JSVAL_TO_OBJECT(js.argv[0]),
-                                NS_GET_IID(nsICanvasRenderingContextGLES11Buffer),
-                                getter_AddRefs(iface));
+        nsCOMPtr<nsICanvasRenderingContextGLBuffer> bufferBase;
+        rv = JSValToSpecificInterface(js.ctx, js.argv[0], (nsICanvasRenderingContextGLBuffer**) getter_AddRefs(bufferBase));
         if (NS_FAILED(rv))
-            return NS_ERROR_DOM_SYNTAX_ERR;
+            return rv;
 
-        // what we want is a CanvasGLES11Buffer; QI to our magic IID
-        // will return this interface
-        nsICanvasRenderingContextGLES11Buffer *bufferBase = nsnull;
-        rv = iface->QueryInterface(CanvasGLES11BufferIID, (void **) &bufferBase);
-        if (NS_FAILED(rv) || !bufferBase)
-            return NS_ERROR_FAILURE;
-
-        newBuffer = NS_STATIC_CAST(CanvasGLES11Buffer*, bufferBase);
+        newBuffer = (CanvasGLBuffer*) bufferBase.get();
 
         if (newBuffer->mType != GL_SHORT &&
             newBuffer->mType != GL_FLOAT)
             return NS_ERROR_DOM_SYNTAX_ERR;
 
         if (newBuffer->mSize != 2)
             return NS_ERROR_DOM_SYNTAX_ERR;
 
@@ -1659,25 +622,23 @@ nsCanvasRenderingContextGLES11::TexCoord
         if (typeParam != GL_SHORT &&
             typeParam != GL_FLOAT)
             return NS_ERROR_DOM_SYNTAX_ERR;
 
         // only 2d textures for now
         if (sizeParam != 2)
             return NS_ERROR_DOM_SYNTAX_ERR;
 
-        newBuffer = new CanvasGLES11Buffer(this);
+        newBuffer = new CanvasGLBuffer(this);
         if (!newBuffer)
             return NS_ERROR_OUT_OF_MEMORY;
 
         rv = newBuffer->Init (GL_STATIC_DRAW, sizeParam, typeParam, js.ctx, arrayObj, arrayLen);
-        if (NS_FAILED(rv)) {
-            delete newBuffer;
+        if (NS_FAILED(rv))
             return rv;
-        }
     } else {
         return NS_ERROR_DOM_SYNTAX_ERR;
     }
 
     mTexCoordBuffer[mActiveTextureUnit] = newBuffer;
 
     MakeContextCurrent();
     glTexCoordPointer(newBuffer->GetSimpleBuffer().sizePerVertex,
@@ -1690,39 +651,26 @@ nsCanvasRenderingContextGLES11::TexCoord
 /* void colorPointer (); */
 NS_IMETHODIMP
 nsCanvasRenderingContextGLES11::ColorPointer()
 {
     NativeJSContext js;
     if (NS_FAILED(js.error))
         return js.error;
 
-    CanvasGLES11Buffer *newBuffer = nsnull;
+    nsRefPtr<CanvasGLBuffer> newBuffer;
     nsresult rv;
 
     if (js.argc == 1) {
-        if (!JSVAL_IS_OBJECT(js.argv[0]) ||
-            JSVAL_IS_NULL(js.argv[0]))
-            return NS_ERROR_DOM_SYNTAX_ERR;
-
-        nsCOMPtr<nsISupports> iface;
-        rv = gXPConnect->WrapJS(js.ctx, JSVAL_TO_OBJECT(js.argv[0]),
-                                NS_GET_IID(nsICanvasRenderingContextGLES11Buffer),
-                                getter_AddRefs(iface));
+        nsCOMPtr<nsICanvasRenderingContextGLBuffer> bufferBase;
+        rv = JSValToSpecificInterface(js.ctx, js.argv[0], (nsICanvasRenderingContextGLBuffer**) getter_AddRefs(bufferBase));
         if (NS_FAILED(rv))
-            return NS_ERROR_DOM_SYNTAX_ERR;
+            return rv;
 
-        // what we want is a CanvasGLES11Buffer; QI to our magic IID
-        // will return this interface
-        nsICanvasRenderingContextGLES11Buffer *bufferBase = nsnull;
-        rv = iface->QueryInterface(CanvasGLES11BufferIID, (void **) &bufferBase);
-        if (NS_FAILED(rv) || !bufferBase)
-            return NS_ERROR_FAILURE;
-
-        newBuffer = NS_STATIC_CAST(CanvasGLES11Buffer*, bufferBase);
+        newBuffer = (CanvasGLBuffer*) bufferBase.get();
 
         if (newBuffer->mType != GL_UNSIGNED_BYTE &&
             newBuffer->mType != GL_FLOAT)
             return NS_ERROR_DOM_SYNTAX_ERR;
 
         if (newBuffer->mSize != 4)
             return NS_ERROR_DOM_SYNTAX_ERR;
     } else if (js.argc == 3) {
@@ -1741,25 +689,23 @@ nsCanvasRenderingContextGLES11::ColorPoi
 
         // XXapi if we're going to require sizeParam to be 4 here,
         // why not just omit the parameter?
         if (typeParam != GL_UNSIGNED_BYTE &&
             typeParam != GL_FLOAT &&
             sizeParam != 4)
             return NS_ERROR_DOM_SYNTAX_ERR;
 
-        newBuffer = new CanvasGLES11Buffer(this);
+        newBuffer = new CanvasGLBuffer(this);
         if (!newBuffer)
             return NS_ERROR_OUT_OF_MEMORY;
 
         rv = newBuffer->Init (GL_STATIC_DRAW, sizeParam, typeParam, js.ctx, arrayObj, arrayLen);
-        if (NS_FAILED(rv)) {
-            delete newBuffer;
+        if (NS_FAILED(rv))
             return rv;
-        }
     }
 
     mColorBuffer = newBuffer;
 
     MakeContextCurrent();
     glColorPointer(newBuffer->GetSimpleBuffer().sizePerVertex,
                    newBuffer->GetSimpleBuffer().type,
                    0,
@@ -1807,21 +753,21 @@ nsCanvasRenderingContextGLES11::DrawElem
     SimpleBuffer indexBuffer;
     JSArrayToSimpleBuffer(indexBuffer, GL_UNSIGNED_SHORT, 1, js.ctx, arrayObj, countParam);
 
     // verify that the indices are valid; we should skip this step
     // if the caller is trusted
     PRUint32 vLen, nLen, cLen;
 
     if (mVertexBuffer)
-        vLen = RealVertexBuffer()->mLength / RealVertexBuffer()->mSize;
+        vLen = mVertexBuffer->mLength / mVertexBuffer->mSize;
     if (mNormalBuffer)
-        nLen = RealNormalBuffer()->mLength / 3;
+        nLen = mNormalBuffer->mLength / 3;
     if (mColorBuffer)
-        cLen = RealColorBuffer()->mLength / 4;
+        cLen = mColorBuffer->mLength / 4;
 
     PRUint16 *indices = (PRUint16*) indexBuffer.data;
     for (PRUint32 i = 0; i < countParam; i++) {
         if ((mVertexArrayEnabled && indices[i] >= vLen) ||
             (mNormalArrayEnabled && indices[i] >= nLen) ||
             (mColorArrayEnabled && indices[i] >= cLen))
             return NS_ERROR_DOM_INDEX_SIZE_ERR;
     }
@@ -2172,46 +1118,46 @@ nsCanvasRenderingContextGLES11::CullFace
     MakeContextCurrent();
     glCullFace(mode);
     return NS_OK;
 }
 
 /* void polygonOffset (in float factor, in float units); */
 GL_SAME_METHOD_2(PolygonOffset, PolygonOffset, float, float)
 
-/* nsICanvasRenderingContextGLES11Texture createTextureObject (in nsIDOMHTMLElement imageOrCanvas); */
+/* nsICanvasRenderingContextGLTexture createTextureObject (in nsIDOMHTMLElement imageOrCanvas); */
 NS_IMETHODIMP
 nsCanvasRenderingContextGLES11::CreateTextureObject(nsIDOMHTMLElement *imageOrCanvas,
-                                                    nsICanvasRenderingContextGLES11Texture **aTextureObject)
+                                                    nsICanvasRenderingContextGLTexture **aTextureObject)
 {
     return NS_ERROR_FAILURE;
 }
 
 NS_IMETHODIMP
-nsCanvasRenderingContextGLES11::BindTextureObject(nsICanvasRenderingContextGLES11Texture *aTextureObject)
+nsCanvasRenderingContextGLES11::BindTextureObject(nsICanvasRenderingContextGLTexture *aTextureObject)
 {
     if (!aTextureObject)
         return NS_ERROR_INVALID_ARG;
 
-    CanvasGLES11Texture *texObj = (CanvasGLES11Texture*) aTextureObject;
+    CanvasGLTexture *texObj = (CanvasGLTexture*) aTextureObject;
     if (texObj->mDisposed)
         return NS_ERROR_INVALID_ARG;
 
     MakeContextCurrent();
     glitz_context_bind_texture(mGlitzContext, texObj->mGlitzTextureObject);
     return NS_OK;
 }
 
 NS_IMETHODIMP
-nsCanvasRenderingContextGLES11::DeleteTextureObject(nsICanvasRenderingContextGLES11Texture *aTextureObject)
+nsCanvasRenderingContextGLES11::DeleteTextureObject(nsICanvasRenderingContextGLTexture *aTextureObject)
 {
     if (!aTextureObject)
         return NS_ERROR_INVALID_ARG;
 
-    CanvasGLES11Texture *texObj = (CanvasGLES11Texture*) aTextureObject;
+    CanvasGLTexture *texObj = (CanvasGLTexture*) aTextureObject;
     if (texObj->mDisposed)
         return NS_ERROR_INVALID_ARG;
 
     MakeContextCurrent();
     texObj->Dispose();
     return NS_OK;
 }
 
@@ -2756,17 +1702,17 @@ nsCanvasRenderingContextGLES11::GetParam
 {
     NativeJSContext js;
     if (NS_FAILED(js.error))
         return js.error;
 
     MakeContextCurrent();
 
     jsval result = JSVAL_VOID;
-    JSObject *rootToRelease = nsnull;
+    JSObject *jsarr = nsnull;
 
     // XXX incomplete
     switch (pname) {
         case GL_ACCUM_ALPHA_BITS:
         case GL_ACCUM_BLUE_BITS:
         case GL_ACCUM_GREEN_BITS:
         case GL_ACCUM_RED_BITS:
         case GL_ALPHA_BIAS:
@@ -2820,56 +1766,52 @@ nsCanvasRenderingContextGLES11::GetParam
             float mat[16];
             glGetFloatv (pname, &mat[0]);
             nsAutoArrayPtr<jsval> jsvector(new jsval[16]);
             for (int i = 0; i < 16; i++) {
                 if (!JS_NewDoubleValue(js.ctx, (jsdouble) mat[i], &jsvector[i]))
                     return NS_ERROR_OUT_OF_MEMORY;
             }
 
-            JSObject *jsarr = JS_NewArrayObject(js.ctx, 16, jsvector.get());
+            jsarr = JS_NewArrayObject(js.ctx, 16, jsvector.get());
             if (!jsarr)
                 return NS_ERROR_OUT_OF_MEMORY;
 
-            js.addGCRoot (jsarr, "glGetParameter");
-            rootToRelease = jsarr;
+            js.AddGCRoot (&jsarr, "glGetParameter");
 
             result = OBJECT_TO_JSVAL(jsarr);
         }
             break;
 
         default:
             return NS_ERROR_NOT_IMPLEMENTED;
     }
 
     if (result == JSVAL_VOID)
         return NS_ERROR_NOT_IMPLEMENTED;
 
-    jsval *retvalPtr;
-    js.ncc->GetRetValPtr(&retvalPtr);
-    *retvalPtr = result;
-    js.ncc->SetReturnValueWasSet(PR_TRUE);
+    js.SetRetVal(result);
 
-    if (rootToRelease)
-        js.releaseGCRoot(rootToRelease);
+    if (jsarr)
+        js.ReleaseGCRoot(&jsarr);
 
     return NS_OK;
 }
 
 #if 0
 NS_IMETHODIMP
 nsCanvasRenderingContextGLES11::BindBufferObject(PRUint32 target,
-                                                 nsICanvasRenderingContextGLES11Buffer *obj)
+                                                 nsICanvasRenderingContextGLBuffer *obj)
 {
     return NS_ERROR_NOT_IMPLEMENTED;
 }
 #endif
 
 NS_IMETHODIMP
-nsCanvasRenderingContextGLES11::CreateBuffer(nsICanvasRenderingContextGLES11Buffer **obj)
+nsCanvasRenderingContextGLES11::CreateBuffer(nsICanvasRenderingContextGLBuffer **obj)
 {
     nsresult rv;
 
     NativeJSContext js;
     if (NS_FAILED(js.error))
         return js.error;
 
     if (js.argc != 4)
@@ -2884,27 +1826,25 @@ nsCanvasRenderingContextGLES11::CreateBu
     if (!::JS_ValueToECMAUint32(js.ctx, js.argv[0], &usageParam) ||
         !::JS_ValueToECMAUint32(js.ctx, js.argv[1], &sizeParam) ||
         !::JS_ValueToECMAUint32(js.ctx, js.argv[2], &typeParam) ||
         !JSValToJSArrayAndLength(js.ctx, js.argv[3], &arrayObj, &arrayLen))
     {
         return NS_ERROR_DOM_SYNTAX_ERR;
     }
 
-    CanvasGLES11Buffer *buffer = new CanvasGLES11Buffer(this);
+    nsRefPtr<CanvasGLBuffer> buffer = new CanvasGLBuffer(this);
     if (!buffer)
         return NS_ERROR_OUT_OF_MEMORY;
 
     rv = buffer->Init(usageParam, sizeParam, typeParam, js.ctx, arrayObj, arrayLen);
-    if (NS_FAILED(rv)) {
-        delete buffer;
+    if (NS_FAILED(rv))
         return rv;
-    }
 
-    NS_ADDREF(*obj = buffer);
+    NS_ADDREF(*obj = buffer.get());
     return NS_OK;
 }
 
 NS_IMETHODIMP
 nsCanvasRenderingContextGLES11::BindBuffer(PRUint32 target, PRUint32 buffer)
 {
     if (target != GL_ARRAY_BUFFER &&
         target != GL_ELEMENT_ARRAY_BUFFER)
@@ -2973,17 +1913,17 @@ nsCanvasRenderingContextGLES11::DeleteBu
     return NS_OK;
 }
 
 /* target, array, type, usage */
 NS_IMETHODIMP
 nsCanvasRenderingContextGLES11::BufferData()
 {
     NativeJSContext js;
-    if (!js.error)
+    if (NS_FAILED(js.error))
         return js.error;
 
     if (js.argc != 3)
         return NS_ERROR_DOM_SYNTAX_ERR;
 
     JSObject *arrayObj;
     jsuint arrayLen;
     jsuint target;
@@ -3006,17 +1946,17 @@ nsCanvasRenderingContextGLES11::BufferDa
     return NS_OK;
 }
 
 /* target, offset, array, type */
 NS_IMETHODIMP
 nsCanvasRenderingContextGLES11::BufferSubData()
 {
     NativeJSContext js;
-    if (!js.error)
+    if (NS_FAILED(js.error))
         return js.error;
 
     if (js.argc != 3)
         return NS_ERROR_DOM_SYNTAX_ERR;
 
     JSObject *arrayObj;
     jsuint arrayLen;
     jsuint target;
@@ -3034,690 +1974,16 @@ nsCanvasRenderingContextGLES11::BufferSu
     if (NS_FAILED(rv))
         return NS_ERROR_DOM_SYNTAX_ERR;
 
     MakeContextCurrent();
     glBufferSubData(target, offset, sbuffer.length * sbuffer.ElementSize(), sbuffer.data);
     return NS_OK;
 }
 
-/**
- ** Helpers that really should be in some sort of cross-context shared library
- **/
-
-nsresult
-nsCanvasRenderingContextGLES11::CairoSurfaceFromElement(nsIDOMElement *imgElt,
-                                                        cairo_surface_t **aCairoSurface,
-                                                        PRUint8 **imgData,
-                                                        PRInt32 *widthOut, PRInt32 *heightOut,
-                                                        nsIURI **uriOut, PRBool *forceWriteOnlyOut)
-{
-    nsresult rv;
-
-    nsCOMPtr<imgIContainer> imgContainer;
-
-    nsCOMPtr<nsIImageLoadingContent> imageLoader = do_QueryInterface(imgElt);
-    if (imageLoader) {
-        nsCOMPtr<imgIRequest> imgRequest;
-        rv = imageLoader->GetRequest(nsIImageLoadingContent::CURRENT_REQUEST,
-                                     getter_AddRefs(imgRequest));
-        NS_ENSURE_SUCCESS(rv, rv);
-        if (!imgRequest)
-            // XXX ERRMSG we need to report an error to developers here! (bug 329026)
-            return NS_ERROR_NOT_AVAILABLE;
-
-        nsCOMPtr<nsIURI> uri;
-        rv = imageLoader->GetCurrentURI(uriOut);
-        NS_ENSURE_SUCCESS(rv, rv);
-       
-        *forceWriteOnlyOut = PR_FALSE;
-
-        rv = imgRequest->GetImage(getter_AddRefs(imgContainer));
-        NS_ENSURE_SUCCESS(rv, rv);
-    } else {
-        // maybe a canvas
-        nsCOMPtr<nsICanvasElement> canvas = do_QueryInterface(imgElt);
-        if (canvas) {
-            PRUint32 w, h;
-            rv = canvas->GetSize(&w, &h);
-            NS_ENSURE_SUCCESS(rv, rv);
-
-            PRUint8 *data = (PRUint8*) PR_Malloc(w * h * 4);
-            cairo_surface_t *surf =
-                cairo_image_surface_create_for_data (data, CAIRO_FORMAT_ARGB32,
-                                                     w, h, w*4);
-            cairo_t *cr = cairo_create (surf);
-            cairo_set_operator (cr, CAIRO_OPERATOR_CLEAR);
-            cairo_paint (cr);
-            cairo_destroy (cr);
-
-            rv = canvas->RenderContextsToSurface(surf);
-            if (NS_FAILED(rv)) {
-                cairo_surface_destroy (surf);
-                return rv;
-            }
-
-            *aCairoSurface = surf;
-            *imgData = data;
-            *widthOut = w;
-            *heightOut = h;
-
-            *uriOut = nsnull;
-            *forceWriteOnlyOut = canvas->IsWriteOnly();
-
-            return NS_OK;
-        } else {
-            NS_WARNING("No way to get surface from non-canvas, non-imageloader");
-            return NS_ERROR_NOT_AVAILABLE;
-        }
-    }
-
-    if (!imgContainer)
-        return NS_ERROR_NOT_AVAILABLE;
-
-    nsCOMPtr<gfxIImageFrame> frame;
-    rv = imgContainer->GetCurrentFrame(getter_AddRefs(frame));
-    NS_ENSURE_SUCCESS(rv, rv);
-
-    nsCOMPtr<nsIImage> img(do_GetInterface(frame));
-
-    PRInt32 imgWidth, imgHeight;
-    rv = frame->GetWidth(&imgWidth);
-    rv |= frame->GetHeight(&imgHeight);
-    if (NS_FAILED(rv))
-        return NS_ERROR_FAILURE;
-
-    if (widthOut)
-        *widthOut = imgWidth;
-    if (heightOut)
-        *heightOut = imgHeight;
-
-#ifdef MOZ_CAIRO_GFX
-    gfxASurface* gfxsurf = nsnull;
-    rv = img->GetSurface(&gfxsurf);
-    NS_ENSURE_SUCCESS(rv, rv);
-
-    *aCairoSurface = gfxsurf->CairoSurface();
-    cairo_surface_reference (*aCairoSurface);
-    *imgData = nsnull;
-#else
-    //
-    // We now need to create a cairo_surface with the same data as
-    // this image element.
-    //
-
-    PRUint8 *cairoImgData = (PRUint8 *)nsMemory::Alloc(imgHeight * imgWidth * 4);
-    PRUint8 *outData = cairoImgData;
-
-    gfx_format format;
-    rv = frame->GetFormat(&format);
-    NS_ENSURE_SUCCESS(rv, rv);
-
-    rv = frame->LockImageData();
-    if (img->GetHasAlphaMask())
-        rv |= frame->LockAlphaData();
-    if (NS_FAILED(rv)) {
-        nsMemory::Free(cairoImgData);
-        return NS_ERROR_FAILURE;
-    }
-
-    PRUint8 *inPixBits, *inAlphaBits = nsnull;
-    PRUint32 inPixStride, inAlphaStride = 0;
-    inPixBits = img->GetBits();
-    inPixStride = img->GetLineStride();
-    if (img->GetHasAlphaMask()) {
-        inAlphaBits = img->GetAlphaBits();
-        inAlphaStride = img->GetAlphaLineStride();
-    }
-
-    PRBool topToBottom = img->GetIsRowOrderTopToBottom();
-    PRBool useBGR;
-
-    // The gtk backend optimizes away the alpha mask of images
-    // with a fully opaque alpha, but doesn't update its format (bug?);
-    // you end up with a RGB_A8 image with GetHasAlphaMask() == false.
-    // We need to treat that case as RGB.
-
-    if ((format == gfxIFormats::RGB || format == gfxIFormats::BGR) ||
-        (!(img->GetHasAlphaMask()) && (format == gfxIFormats::RGB_A8 || format == gfxIFormats::BGR_A8)))
-    {
-        useBGR = (format & 1);
-
-#ifdef IS_BIG_ENDIAN
-        useBGR = !useBGR;
-#endif
-
-        for (PRUint32 j = 0; j < (PRUint32) imgHeight; j++) {
-            PRUint32 rowIndex;
-            if (topToBottom)
-                rowIndex = j;
-            else
-                rowIndex = imgHeight - j - 1;
-
-            PRUint8 *inrowrgb = inPixBits + (inPixStride * rowIndex);
-
-            for (PRUint32 i = 0; i < (PRUint32) imgWidth; i++) {
-                // handle rgb data; no alpha to premultiply
-#ifdef XP_MACOSX
-                // skip extra OSX byte
-                inrowrgb++;
-#endif
-                PRUint8 r, g, b;
-                if (useBGR) {
-                    b = *inrowrgb++;
-                    g = *inrowrgb++;
-                    r = *inrowrgb++;
-                } else {
-                    r = *inrowrgb++;
-                    g = *inrowrgb++;
-                    b = *inrowrgb++;
-                }
-
-#ifdef IS_BIG_ENDIAN
-                // alpha
-                *outData++ = 0xff;
-#endif
-
-                *outData++ = r;
-                *outData++ = g;
-                *outData++ = b;
-
-#ifdef IS_LITTLE_ENDIAN
-                // alpha
-                *outData++ = 0xff;
-#endif
-            }
-        }
-        rv = NS_OK;
-    } else if (format == gfxIFormats::RGB_A1 || format == gfxIFormats::BGR_A1) {
-        useBGR = (format & 1);
-
-#ifdef IS_BIG_ENDIAN
-        useBGR = !useBGR;
-#endif
-
-        for (PRUint32 j = 0; j < (PRUint32) imgHeight; j++) {
-            PRUint32 rowIndex;
-            if (topToBottom)
-                rowIndex = j;
-            else
-                rowIndex = imgHeight - j - 1;
-
-            PRUint8 *inrowrgb = inPixBits + (inPixStride * rowIndex);
-            PRUint8 *inrowalpha = inAlphaBits + (inAlphaStride * rowIndex);
-
-            for (PRUint32 i = 0; i < (PRUint32) imgWidth; i++) {
-                // pull out the bit value into alpha
-                PRInt32 bit = i % 8;
-                PRInt32 byte = i / 8;
-
-#ifdef IS_LITTLE_ENDIAN
-                PRUint8 a = (inrowalpha[byte] >> (7-bit)) & 1;
-#else
-                PRUint8 a = (inrowalpha[byte] >> bit) & 1;
-#endif
-
-#ifdef XP_MACOSX
-                // skip extra X8 byte on OSX
-                inrowrgb++;
-#endif
-
-                // handle rgb data; need to multiply the alpha out,
-                // but we short-circuit that here since we know that a
-                // can only be 0 or 1
-                if (a) {
-                    PRUint8 r, g, b;
-
-                    if (useBGR) {
-                        b = *inrowrgb++;
-                        g = *inrowrgb++;
-                        r = *inrowrgb++;
-                    } else {
-                        r = *inrowrgb++;
-                        g = *inrowrgb++;
-                        b = *inrowrgb++;
-                    }
-
-#ifdef IS_BIG_ENDIAN
-                    // alpha
-                    *outData++ = 0xff;
-#endif
-
-                    *outData++ = r;
-                    *outData++ = g;
-                    *outData++ = b;
-
-#ifdef IS_LITTLE_ENDIAN
-                    // alpha
-                    *outData++ = 0xff;
-#endif
-                } else {
-                    // alpha is 0, so we need to write all 0's,
-                    // ignoring input color
-                    inrowrgb += 3;
-                    *outData++ = 0;
-                    *outData++ = 0;
-                    *outData++ = 0;
-                    *outData++ = 0;
-                }
-            }
-        }
-        rv = NS_OK;
-    } else if (format == gfxIFormats::RGB_A8 || format == gfxIFormats::BGR_A8) {
-        useBGR = (format & 1);
-
-#ifdef IS_BIG_ENDIAN
-        useBGR = !useBGR;
-#endif
-
-        for (PRUint32 j = 0; j < (PRUint32) imgHeight; j++) {
-            PRUint32 rowIndex;
-            if (topToBottom)
-                rowIndex = j;
-            else
-                rowIndex = imgHeight - j - 1;
-
-            PRUint8 *inrowrgb = inPixBits + (inPixStride * rowIndex);
-            PRUint8 *inrowalpha = inAlphaBits + (inAlphaStride * rowIndex);
-
-            for (PRUint32 i = 0; i < (PRUint32) imgWidth; i++) {
-                // pull out alpha; we'll need it to premultiply
-                PRUint8 a = *inrowalpha++;
-
-                // handle rgb data; we need to fully premultiply
-                // with the alpha
-#ifdef XP_MACOSX
-                // skip extra X8 byte on OSX
-                inrowrgb++;
-#endif
-
-                // XXX gcc bug: gcc seems to push "r" into a register
-                // early, and pretends that it's in that register
-                // throughout the 3 macros below.  At the end
-                // of the 3rd macro, the correct r value is
-                // calculated but never stored anywhere -- the r variable
-                // has the value of the low byte of register that it
-                // was stuffed into, which has the result of some 
-                // intermediate calculation.
-                // I've seen this on gcc 3.4.2 x86 (Fedora Core 3)
-                // and gcc 3.3 PPC (OS X 10.3)
-
-                //PRUint8 b, g, r;
-                //FAST_DIVIDE_BY_255(b, *inrowrgb++ * a - a / 2);
-                //FAST_DIVIDE_BY_255(g, *inrowrgb++ * a - a / 2);
-                //FAST_DIVIDE_BY_255(r, *inrowrgb++ * a - a / 2);
-
-                PRUint8 r, g, b;
-                if (useBGR) {
-                    b = (*inrowrgb++ * a - a / 2) / 255;
-                    g = (*inrowrgb++ * a - a / 2) / 255;
-                    r = (*inrowrgb++ * a - a / 2) / 255;
-                } else {
-                    r = (*inrowrgb++ * a - a / 2) / 255;
-                    g = (*inrowrgb++ * a - a / 2) / 255;
-                    b = (*inrowrgb++ * a - a / 2) / 255;
-                }
-
-#ifdef IS_BIG_ENDIAN
-                *outData++ = a;
-#endif
-
-                *outData++ = r;
-                *outData++ = g;
-                *outData++ = b;
-
-#ifdef IS_LITTLE_ENDIAN
-                *outData++ = a;
-#endif
-            }
-        }
-        rv = NS_OK;
-    } else {
-        rv = NS_ERROR_FAILURE;
-    }
-
-    if (img->GetHasAlphaMask())
-        frame->UnlockAlphaData();
-    frame->UnlockImageData();
-
-    if (NS_FAILED(rv)) {
-        nsMemory::Free(cairoImgData);
-        return rv;
-    }
-
-    cairo_surface_t *imgSurf =
-        cairo_image_surface_create_for_data(cairoImgData, CAIRO_FORMAT_ARGB32,
-                                            imgWidth, imgHeight, imgWidth*4);
-
-    *aCairoSurface = imgSurf;
-    *imgData = cairoImgData;
-#endif
-
-    return NS_OK;
-}
-
-void
-nsCanvasRenderingContextGLES11::DoDrawImageSecurityCheck(nsIURI* aURI, PRBool forceWriteOnly)
-{
-    /* So; this is causing dll woes under win32.  Until we figure that out, we just return. */
-    return;
-
-#if 0
-    fprintf (stderr, "DoDrawImageSecuritycheck this 1: %p\n", this);
-    if (mCanvasElement->IsWriteOnly())
-        return;
-
-    fprintf (stderr, "DoDrawImageSecuritycheck this 2: %p\n", this);
-    if (!aURI)
-        return;
-
-    fprintf (stderr, "DoDrawImageSecuritycheck this 3: %p\n", this);
-    if (forceWriteOnly) {
-        mCanvasElement->SetWriteOnly();
-        return;
-    }
-
-    fprintf (stderr, "DoDrawImageSecuritycheck this 4: %p\n", this);
-    nsCOMPtr<nsIScriptSecurityManager> ssm =
-        do_GetService(NS_SCRIPTSECURITYMANAGER_CONTRACTID);
-    if (!ssm) {
-        mCanvasElement->SetWriteOnly();
-        return;
-    }
-
-    fprintf (stderr, "DoDrawImageSecuritycheck this 5: %p\n", this);
-#ifdef MOZILLA_1_8_BRANCH
-#if 0
-    nsCOMPtr<nsIDOMNode> elem = do_QueryInterface(mCanvasElement);
-    if (elem && ssm) {
-        nsCOMPtr<nsIPrincipal> elemPrincipal;
-        nsCOMPtr<nsIPrincipal> uriPrincipal;
-        nsCOMPtr<nsIDocument> elemDocument;
-        nsContentUtils::GetDocumentAndPrincipal(elem, getter_AddRefs(elemDocument), getter_AddRefs(elemPrincipal));
-        ssm->GetCodebasePrincipal(aURI, getter_AddRefs(uriPrincipal));
-
-        if (uriPrincipal && elemPrincipal) {
-            nsresult rv =
-                ssm->CheckSameOriginPrincipal(elemPrincipal, uriPrincipal);
-            if (NS_SUCCEEDED(rv)) {
-                // Same origin
-                return;
-            }
-        }
-    }
-#endif
-#else
-    nsCOMPtr<nsINode> elem = do_QueryInterface(mCanvasElement);
-    if (elem && ssm) {
-        nsCOMPtr<nsIPrincipal> uriPrincipal;
-        ssm->GetCodebasePrincipal(aURI, getter_AddRefs(uriPrincipal));
-
-        if (uriPrincipal) {
-            nsresult rv = ssm->CheckSameOriginPrincipal(elem->NodePrincipal(),
-                                                        uriPrincipal);
-            if (NS_SUCCEEDED(rv)) {
-                // Same origin
-                return;
-            }
-        }
-    }
-#endif
-
-    fprintf (stderr, "DoDrawImageSecuritycheck this 6: %p\n", this); fflush(stderr);
-    mCanvasElement->SetWriteOnly();
-#endif
-}
-
-/**
- ** CanvasGLES11Texture
- **/
-
-CanvasGLES11Texture::CanvasGLES11Texture(nsCanvasRenderingContextGLES11 *owner)
-    : mDisposed(PR_FALSE), mOwnerContext (owner),
-      mGlitzTextureSurface(nsnull), mGlitzTextureObject(nsnull),
-      mWidth(0), mHeight(0)
-{
-}
-
-CanvasGLES11Texture::~CanvasGLES11Texture()
-{
-    Dispose();
-}
-
-nsresult
-CanvasGLES11Texture::Init()
-{
-    return NS_OK;
-}
-
-nsresult
-CanvasGLES11Texture::Dispose()
-{
-    if (mDisposed)
-        return NS_OK;
-
-    mDisposed = PR_TRUE;
-    return NS_OK;
-}
-
-NS_IMETHODIMP
-CanvasGLES11Texture::GetDisposed(PRBool *retval)
-{
-    *retval = mDisposed;
-    return NS_OK;
-}
-
-NS_IMETHODIMP
-CanvasGLES11Texture::GetOwnerContext(nsICanvasRenderingContextGLES11 **ownerContext)
-{
-    *ownerContext = mOwnerContext;
-    return NS_OK;
-}
-
-NS_IMETHODIMP
-CanvasGLES11Texture::GetTarget(PRUint32 *aResult)
-{
-    *aResult = glitz_texture_object_get_target (mGlitzTextureObject);
-    return NS_OK;
-}
-
-NS_IMETHODIMP
-CanvasGLES11Texture::GetWidth(PRUint32 *aWidth)
-{
-    *aWidth = mWidth;
-    return NS_OK;
-}
-
-NS_IMETHODIMP
-CanvasGLES11Texture::GetHeight(PRUint32 *aHeight)
-{
-    *aHeight = mHeight;
-    return NS_OK;
-}
-
-NS_IMETHODIMP
-CanvasGLES11Texture::SetFilter(PRUint32 filterType, PRUint32 filterMode)
-{
-    if (filterType < 0 || filterType > 1 ||
-        filterMode < 0 || filterMode > 1)
-    {
-        return NS_ERROR_DOM_SYNTAX_ERR;
-    }
-
-    glitz_texture_object_set_filter (mGlitzTextureObject, (glitz_texture_filter_type_t)filterType, (glitz_texture_filter_t)filterMode);
-    return NS_OK;
-}
-
-NS_IMETHODIMP
-CanvasGLES11Texture::SetWrap(PRUint32 wrapType, PRUint32 wrapMode)
-{
-    if (wrapType != GLITZ_TEXTURE_WRAP_TYPE_S &&
-        wrapType != GLITZ_TEXTURE_WRAP_TYPE_T)
-        return NS_ERROR_DOM_SYNTAX_ERR;
-
-    if (wrapMode != GLITZ_TEXTURE_WRAP_CLAMP_TO_EDGE &&
-        wrapMode != GLITZ_TEXTURE_WRAP_REPEAT &&
-        wrapMode != GLITZ_TEXTURE_WRAP_MIRRORED_REPEAT)
-        return NS_ERROR_DOM_SYNTAX_ERR;
-
-    glitz_texture_object_set_wrap (mGlitzTextureObject, (glitz_texture_wrap_type_t)wrapType, (glitz_texture_wrap_t)wrapMode);
-    return NS_OK;
-}
-
-/**
- ** CanvasGLES11Buffer
- **/
-
-CanvasGLES11Buffer::CanvasGLES11Buffer(nsCanvasRenderingContextGLES11 *owner)
-    : mDisposed(PR_TRUE), mOwnerContext(owner),
-      mLength(0), mSize(0), mType(0), mUsage(GL_STATIC_DRAW),
-      mBufferID(0)
-{
-}
-
-CanvasGLES11Buffer::~CanvasGLES11Buffer()
-{
-    Dispose();
-}
-
-/* nsISecurityCheckedComponent bits */
-
-static char* cloneAllAccess()
-{
-    static const char allAccess[] = "allAccess";
-    return (char*)nsMemory::Clone(allAccess, sizeof(allAccess));
-}
-
-NS_IMETHODIMP
-CanvasGLES11Buffer::CanCreateWrapper(const nsIID* iid, char **_retval) {
-    *_retval = cloneAllAccess();
-    return NS_OK;
-}
-
-NS_IMETHODIMP
-CanvasGLES11Buffer::CanCallMethod(const nsIID *iid, const PRUnichar *methodName, char **_retval) {
-    *_retval = cloneAllAccess();
-    return NS_OK;
-}
-
-NS_IMETHODIMP
-CanvasGLES11Buffer::CanGetProperty(const nsIID *iid, const PRUnichar *propertyName, char **_retval) {
-    *_retval = cloneAllAccess();
-    return NS_OK;
-}
-
-NS_IMETHODIMP
-CanvasGLES11Buffer::CanSetProperty(const nsIID *iid, const PRUnichar *propertyName, char **_retval) {
-    *_retval = cloneAllAccess();
-    return NS_OK;
-}
-
-GLEWContext*
-CanvasGLES11Buffer::glewGetContext()
-{
-    return mOwnerContext->glewGetContext();
-}
-
-nsresult
-CanvasGLES11Buffer::Init(PRUint32 usage,
-                         PRUint32 size,
-                         PRUint32 type,
-                         JSContext *ctx,
-                         JSObject *arrayObj,
-                         jsuint arrayLen)
-{
-    nsresult rv;
-
-    fprintf (stderr, "CanvasGLES11Buffer::Init\n");
-
-    if (!mDisposed)
-        Dispose();
-
-    if (usage != GL_STATIC_DRAW &&
-        usage != GL_DYNAMIC_DRAW)
-        return NS_ERROR_INVALID_ARG;
-
-    rv = nsCanvasRenderingContextGLES11::JSArrayToSimpleBuffer(mSimpleBuffer, type, size, ctx, arrayObj, arrayLen);
-    if (NS_FAILED(rv))
-        return rv;
-
-    mUsage = usage;
-    mSize = size;
-    mType = type;
-    mLength = arrayLen;
-
-    mBufferID = 0;
-
-    mDisposed = PR_FALSE;
-
-    return NS_OK;
-}
-
-NS_IMETHODIMP
-CanvasGLES11Buffer::Dispose()
-{
-    if (mDisposed)
-        return NS_OK;
-
-    if (mBufferID) {
-        mOwnerContext->MakeContextCurrent();
-        glDeleteBuffers(1, &mBufferID);
-        mBufferID = 0;
-    }
-
-    mSimpleBuffer.Release();
-
-    mDisposed = PR_TRUE;
-    return NS_OK;
-}
-
-NS_IMETHODIMP
-CanvasGLES11Buffer::GetOwnerContext(nsICanvasRenderingContextGLES11 **retval)
-{
-    *retval = mOwnerContext;
-    return NS_OK;
-}
-
-NS_IMETHODIMP
-CanvasGLES11Buffer::GetDisposed(PRBool *retval)
-{
-    *retval = mDisposed;
-    return NS_OK;
-}
-
-NS_IMETHODIMP
-CanvasGLES11Buffer::GetUsage(PRUint32 *usage)
-{
-    if (mDisposed)
-        return NS_ERROR_FAILURE;
-
-    *usage = mUsage;
-    return NS_OK;
-}
-
-NS_IMETHODIMP
-CanvasGLES11Buffer::GetLength(PRUint32 *retval)
-{
-    if (mDisposed)
-        return NS_ERROR_FAILURE;
-
-    *retval = mLength;
-    return NS_OK;
-}
-
-NS_IMETHODIMP
-CanvasGLES11Buffer::GetType(PRUint32 *retval)
-{
-    if (mDisposed)
-        return NS_ERROR_FAILURE;
-
-    *retval = mType;
-    return NS_OK;
-}
-
 /*
  * Utils yay!
  */
 
 NS_IMETHODIMP
 nsCanvasRenderingContextGLES11::GluPerspective(float fovy, float apsect, float znear, float zfar)
 {
     MakeContextCurrent();
new file mode 100644
--- /dev/null
+++ b/extensions/canvas3d/src/nsCanvasRenderingContextGLWeb20.cpp
@@ -0,0 +1,1458 @@
+/* -*- 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) 2006
+ * 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 "prmem.h"
+#include "prlog.h"
+
+#include "nsIRenderingContext.h"
+
+#define NSGL_CONTEXT_NAME nsCanvasRenderingContextGLWeb20
+
+#include "nsCanvasRenderingContextGL.h"
+#include "nsICanvasRenderingContextGLWeb20.h"
+#include "nsICanvasRenderingContextInternal.h"
+#include "nsIDOMHTMLCanvasElement.h"
+#include "nsIView.h"
+#include "nsIViewManager.h"
+
+#ifndef MOZILLA_1_8_BRANCH
+#include "nsIDocument.h"
+#endif
+
+#include "nsTransform2D.h"
+
+#include "nsIScriptSecurityManager.h"
+#include "nsISecurityCheckedComponent.h"
+
+#include "nsWeakReference.h"
+
+#include "imgIRequest.h"
+#include "imgIContainer.h"
+#include "gfxIImageFrame.h"
+#include "nsIDOMHTMLCanvasElement.h"
+#include "nsICanvasElement.h"
+#include "nsIDOMHTMLImageElement.h"
+#include "nsIImageLoadingContent.h"
+#include "nsIInterfaceRequestorUtils.h"
+#include "nsIImage.h"
+#include "nsIFrame.h"
+#include "nsDOMError.h"
+#include "nsIJSRuntimeService.h"
+
+#ifndef MOZILLA_1_8_BRANCH
+#include "nsIClassInfoImpl.h"
+#endif
+
+#include "nsServiceManagerUtils.h"
+
+#include "nsDOMError.h"
+
+#include "nsContentUtils.h"
+
+#include "nsIXPConnect.h"
+#include "jsapi.h"
+
+#ifdef MOZ_CAIRO_GFX
+#include "gfxContext.h"
+#include "gfxASurface.h"
+#endif
+
+#ifdef XP_WIN
+#include <windows.h>
+#endif
+
+// GLEW will pull in the GL bits that we want/need
+#include "glew.h"
+
+// we're hoping that something is setting us up the remap
+
+#include "cairo.h"
+#include "glitz.h"
+
+#ifdef MOZ_X11
+#include <gdk/gdk.h>
+#include <gdk/gdkx.h>
+#include "cairo-xlib.h"
+#include "glitz-glx.h"
+#endif
+
+#ifdef XP_WIN
+#include "cairo-win32.h"
+#include "glitz-wgl.h"
+#endif
+
+#ifdef PR_LOGGING
+PRLogModuleInfo* gGLES20Log = nsnull;
+#endif
+
+class nsCanvasRenderingContextGLWeb20 :
+    public nsICanvasRenderingContextGLWeb20,
+    public nsCanvasRenderingContextGLPrivate
+{
+public:
+    nsCanvasRenderingContextGLWeb20();
+    virtual ~nsCanvasRenderingContextGLWeb20();
+
+    NS_DECL_ISUPPORTS
+
+    NS_DECL_NSICANVASRENDERINGCONTEXTGL
+
+    NS_DECL_NSICANVASRENDERINGCONTEXTGLWEB20
+
+    // nsICanvasRenderingContextPrivate
+    virtual nsICanvasRenderingContextGL *GetSelf() { return this; }
+    virtual PRBool ValidateGL();
+};
+
+
+// nsCanvasRenderingContextGLWeb20
+// NS_DECL_CLASSINFO lives in nsCanvas3DModule
+NS_IMPL_ADDREF(nsCanvasRenderingContextGLWeb20)
+NS_IMPL_RELEASE(nsCanvasRenderingContextGLWeb20)
+
+NS_IMPL_CI_INTERFACE_GETTER4(nsCanvasRenderingContextGLWeb20,
+                             nsICanvasRenderingContextGL,
+                             nsICanvasRenderingContextGLWeb20,
+                             nsICanvasRenderingContextInternal,
+                             nsISupportsWeakReference)
+
+NS_INTERFACE_MAP_BEGIN(nsCanvasRenderingContextGLWeb20)
+  NS_INTERFACE_MAP_ENTRY(nsICanvasRenderingContextGL)
+  NS_INTERFACE_MAP_ENTRY(nsICanvasRenderingContextGLWeb20)
+  NS_INTERFACE_MAP_ENTRY(nsICanvasRenderingContextInternal)
+  NS_INTERFACE_MAP_ENTRY(nsISupportsWeakReference)
+  NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsICanvasRenderingContextGL)
+  NS_IMPL_QUERY_CLASSINFO(nsCanvasRenderingContextGLWeb20)
+NS_INTERFACE_MAP_END
+
+nsresult
+NS_NewCanvasRenderingContextGLWeb20(nsICanvasRenderingContextGLWeb20** aResult)
+{
+    nsICanvasRenderingContextGLWeb20* ctx = new nsCanvasRenderingContextGLWeb20();
+    if (!ctx)
+        return NS_ERROR_OUT_OF_MEMORY;
+
+    NS_ADDREF(*aResult = ctx);
+    return NS_OK;
+}
+
+nsCanvasRenderingContextGLWeb20::nsCanvasRenderingContextGLWeb20()
+{
+}
+
+nsCanvasRenderingContextGLWeb20::~nsCanvasRenderingContextGLWeb20()
+{
+}
+
+NS_IMETHODIMP
+nsCanvasRenderingContextGLWeb20::GetCanvas(nsIDOMHTMLCanvasElement **_retval)
+{
+    *_retval = nsnull;
+    return NS_OK;
+}
+
+/* void activeTexture (in PRUint32 texture); */
+NS_IMETHODIMP
+nsCanvasRenderingContextGLWeb20::ActiveTexture(PRUint32 texture)
+{
+    if (!GLEW_ARB_multitexture) {
+        if (texture == GL_TEXTURE0)
+            return NS_OK;
+        return NS_ERROR_NOT_IMPLEMENTED;
+    }
+
+    if (texture < GL_TEXTURE0 || texture > GL_TEXTURE0+32)
+        return NS_ERROR_DOM_SYNTAX_ERR;
+
+    glActiveTexture(texture);
+    return NS_OK;
+}
+
+GL_SAME_METHOD_2(AttachShader, AttachShader, PRUint32, PRUint32)
+
+GL_SAME_METHOD_3(BindAttribLocation, BindAttribLocation, PRUint32, PRUint32, const char*)
+
+GL_SAME_METHOD_2(BindBuffer, BindBuffer, PRUint32, PRUint32)
+
+GL_SAME_METHOD_2(BindTexture, BindTexture, PRUint32, PRUint32)
+
+GL_SAME_METHOD_4(BlendColor, BlendColor, float, float, float, float)
+
+GL_SAME_METHOD_1(BlendEquation, BlendEquation, PRUint32)
+
+GL_SAME_METHOD_2(BlendEquationSeparate, BlendEquationSeparate, PRUint32, PRUint32)
+
+GL_SAME_METHOD_2(BlendFunc, BlendFunc, PRUint32, PRUint32)
+
+GL_SAME_METHOD_4(BlendFuncSeparate, BlendFuncSeparate, PRUint32, PRUint32, PRUint32, PRUint32)
+
+/* target, array, type, usage */
+NS_IMETHODIMP
+nsCanvasRenderingContextGLWeb20::BufferData()
+{
+    NativeJSContext js;
+    if (NS_FAILED(js.error))
+        return js.error;
+
+    if (js.argc != 3)
+        return NS_ERROR_DOM_SYNTAX_ERR;
+
+    JSObject *arrayObj;
+    jsuint arrayLen;
+    jsuint target;
+    jsuint type;
+    jsuint usage;
+    if (!::JS_ConvertArguments(js.ctx, js.argc, js.argv, "uouu", &target, &arrayObj, &type, &usage) ||
+        !::JS_IsArrayObject(js.ctx, arrayObj) ||
+        !::JS_GetArrayLength(js.ctx, arrayObj, &arrayLen))
+    {
+        return NS_ERROR_DOM_SYNTAX_ERR;
+    }
+
+    SimpleBuffer sbuffer;
+    nsresult rv = JSArrayToSimpleBuffer(sbuffer, type, 1, js.ctx, arrayObj, arrayLen);
+    if (NS_FAILED(rv))
+        return NS_ERROR_DOM_SYNTAX_ERR;
+
+    MakeContextCurrent();
+    glBufferData(target, sbuffer.length * sbuffer.ElementSize(), sbuffer.data, usage);
+    return NS_OK;
+}
+
+/* target, offset, array, type */
+NS_IMETHODIMP
+nsCanvasRenderingContextGLWeb20::BufferSubData()
+{
+    NativeJSContext js;
+    if (NS_FAILED(js.error))
+        return js.error;
+
+    if (js.argc != 3)
+        return NS_ERROR_DOM_SYNTAX_ERR;
+
+    JSObject *arrayObj;
+    jsuint arrayLen;
+    jsuint target;
+    jsuint offset;
+    jsuint type;
+    if (!::JS_ConvertArguments(js.ctx, js.argc, js.argv, "uuou", &target, &offset, &arrayObj, &type) ||
+        !::JS_IsArrayObject(js.ctx, arrayObj) ||
+        !::JS_GetArrayLength(js.ctx, arrayObj, &arrayLen))
+    {
+        return NS_ERROR_DOM_SYNTAX_ERR;
+    }
+
+    SimpleBuffer sbuffer;
+    nsresult rv = JSArrayToSimpleBuffer(sbuffer, type, 1, js.ctx, arrayObj, arrayLen);
+    if (NS_FAILED(rv))
+        return NS_ERROR_DOM_SYNTAX_ERR;
+
+    MakeContextCurrent();
+    glBufferSubData(target, offset, sbuffer.length * sbuffer.ElementSize(), sbuffer.data);
+    return NS_OK;
+}
+
+GL_SAME_METHOD_1(Clear, Clear, PRUint32);
+
+GL_SAME_METHOD_4(ClearColor, ClearColor, float, float, float, float);
+
+GL_SAME_METHOD_1(ClearDepth, ClearDepth, float);
+
+GL_SAME_METHOD_1(ClearStencil, ClearStencil, PRInt32);
+
+GL_SAME_METHOD_4(ColorMask, ColorMask, PRBool, PRBool, PRBool, PRBool);
+
+NS_IMETHODIMP
+nsCanvasRenderingContextGLWeb20::CreateProgram(PRUint32 *retval)
+{
+    MakeContextCurrent();
+    *retval = glCreateProgram();
+    return NS_OK;
+}
+
+NS_IMETHODIMP
+nsCanvasRenderingContextGLWeb20::CreateShader(PRUint32 type, PRUint32 *retval)
+{
+    MakeContextCurrent();
+    *retval = glCreateShader(type);
+    return NS_OK;
+}
+
+GL_SAME_METHOD_1(CullFace, CullFace, PRUint32);
+
+NS_IMETHODIMP
+nsCanvasRenderingContextGLWeb20::DeleteBuffers()
+{
+    NativeJSContext js;
+    if (NS_FAILED(js.error))
+        return js.error;
+
+    if (js.argc != 1)
+        return NS_ERROR_DOM_SYNTAX_ERR;
+
+    JSObject *arrayObj;
+    jsuint arrayLen;
+    if (!JSValToJSArrayAndLength(js.ctx, js.argv[0], &arrayObj, &arrayLen))
+        return NS_ERROR_DOM_SYNTAX_ERR;
+
+    if (arrayLen == 0)
+        return NS_OK;
+
+    SimpleBuffer sbuffer;
+    nsresult rv = JSArrayToSimpleBuffer(sbuffer, GL_UNSIGNED_INT, 1, js.ctx, arrayObj, arrayLen);
+    if (NS_FAILED(rv))
+        return NS_ERROR_DOM_SYNTAX_ERR;
+
+    MakeContextCurrent();
+    glDeleteBuffers(arrayLen, (GLuint*) sbuffer.data);
+
+    return NS_OK;
+}
+
+NS_IMETHODIMP
+nsCanvasRenderingContextGLWeb20::DeleteTextures()
+{
+    NativeJSContext js;
+    if (NS_FAILED(js.error))
+        return js.error;
+
+    if (js.argc != 1)
+        return NS_ERROR_DOM_SYNTAX_ERR;
+
+    JSObject *arrayObj;
+    jsuint arrayLen;
+    if (!JSValToJSArrayAndLength(js.ctx, js.argv[0], &arrayObj, &arrayLen))
+        return NS_ERROR_DOM_SYNTAX_ERR;
+
+    if (arrayLen == 0)
+        return NS_OK;
+
+    SimpleBuffer sbuffer;
+    nsresult rv = JSArrayToSimpleBuffer(sbuffer, GL_UNSIGNED_INT, 1, js.ctx, arrayObj, arrayLen);
+    if (NS_FAILED(rv))
+        return NS_ERROR_DOM_SYNTAX_ERR;
+
+    MakeContextCurrent();
+    glDeleteTextures(arrayLen, (GLuint*) sbuffer.data);
+
+    return NS_OK;
+}
+
+GL_SAME_METHOD_1(DeleteProgram, DeleteProgram, PRUint32)
+
+GL_SAME_METHOD_1(DeleteShader, DeleteShader, PRUint32)
+
+GL_SAME_METHOD_2(DetachShader, DetachShader, PRUint32, PRUint32)
+
+GL_SAME_METHOD_1(DepthFunc, DepthFunc, PRUint32)
+
+GL_SAME_METHOD_1(DepthMask, DepthMask, PRBool)
+
+GL_SAME_METHOD_2(DepthRange, DepthRange, float, float)
+
+GL_SAME_METHOD_1(Disable, Disable, PRUint32)
+
+GL_SAME_METHOD_1(DisableVertexAttribArray, DisableVertexAttribArray, PRUint32)
+
+GL_SAME_METHOD_3(DrawArrays, DrawArrays, PRUint32, PRUint32, PRUint32)
+
+// DrawElements
+NS_IMETHODIMP
+nsCanvasRenderingContextGLWeb20::DrawElements()
+{
+    return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+GL_SAME_METHOD_1(Enable, Enable, PRUint32)
+
+GL_SAME_METHOD_1(EnableVertexAttribArray, EnableVertexAttribArray, PRUint32)
+
+GL_SAME_METHOD_1(FrontFace, FrontFace, PRUint32)
+
+// returns an object: { size: ..., type: ..., name: ... }
+NS_IMETHODIMP
+nsCanvasRenderingContextGLWeb20::GetActiveAttrib(PRUint32 program, PRUint32 index)
+{
+    NativeJSContext js;
+    if (NS_FAILED(js.error))
+        return js.error;
+
+    MakeContextCurrent();
+
+    int len;
+    glGetProgramiv(program, GL_ACTIVE_ATTRIBUTE_MAX_LENGTH, &len);
+    if (len == 0)
+        return NS_ERROR_FAILURE;
+
+    nsAutoArrayPtr<char> name = new char[len+1];
+    PRInt32 attrsize;
+    PRUint32 attrtype;
+
+    glGetActiveAttrib(program, index, len+1, &len, &attrsize, &attrtype, name);
+
+    JSObjectHelper retobj(&js);
+    retobj.DefineProperty("size", attrsize);
+    retobj.DefineProperty("type", attrtype);
+    retobj.DefineProperty("name", name, len);
+
+    js.SetRetVal(OBJECT_TO_JSVAL(retobj.Object()));
+
+    return NS_OK;
+}
+
+NS_IMETHODIMP
+nsCanvasRenderingContextGLWeb20::GetActiveUniform(PRUint32 program, PRUint32 index)
+{
+    NativeJSContext js;
+    if (NS_FAILED(js.error))
+        return js.error;
+
+    MakeContextCurrent();
+
+    int len;
+    glGetProgramiv(program, GL_ACTIVE_UNIFORM_MAX_LENGTH, &len);
+    if (len == 0)
+        return NS_ERROR_FAILURE;
+
+    nsAutoArrayPtr<char> name = new char[len+1];
+    PRInt32 attrsize;
+    PRUint32 attrtype;
+
+    glGetActiveUniform(program, index, len+1, &len, &attrsize, &attrtype, name);
+
+    JSObjectHelper retobj(&js);
+    retobj.DefineProperty("size", attrsize);
+    retobj.DefineProperty("type", attrtype);
+    retobj.DefineProperty("name", name, len);
+
+    js.SetRetVal(OBJECT_TO_JSVAL(retobj.Object()));
+
+    return NS_OK;
+}
+
+NS_IMETHODIMP
+nsCanvasRenderingContextGLWeb20::GetAttachedShaders(PRUint32 program)
+{
+    NativeJSContext js;
+    if (NS_FAILED(js.error))
+        return js.error;
+
+    MakeContextCurrent();
+
+    int count;
+    glGetProgramiv(program, GL_ATTACHED_SHADERS, &count);
+
+    nsAutoArrayPtr<PRUint32> shaders = new PRUint32[count];
+
+    glGetAttachedShaders(program, count, NULL, shaders);
+
+    JSObject *obj = ArrayToJSArray(js.ctx, shaders, count);
+
+    js.AddGCRoot(obj, "GetAttachedShaders");
+    js.SetRetVal(OBJECT_TO_JSVAL(obj));
+    js.ReleaseGCRoot(obj);
+
+    return NS_OK;
+}
+
+NS_IMETHODIMP
+nsCanvasRenderingContextGLWeb20::GetAttribLocation(PRUint32 program,
+                                                   const char *name,
+                                                   PRInt32 *retval)
+{
+    MakeContextCurrent();
+    *retval = glGetAttribLocation(program, name);
+    return NS_OK;
+}
+
+NS_IMETHODIMP
+nsCanvasRenderingContextGLWeb20::GetParameter(PRUint32 pname)
+{
+    NativeJSContext js;
+    if (NS_FAILED(js.error))
+        return js.error;
+
+    MakeContextCurrent();
+
+    switch (pname) {
+        //
+        // String params
+        //
+
+        // XXX do we want to fake these?  Could be a problem to reveal this to web content
+        case GL_VENDOR:
+        case GL_RENDERER:
+        case GL_VERSION:
+        case GL_SHADING_LANGUAGE_VERSION:
+        //case GL_EXTENSIONS:  // Not going to expose this
+
+            break;
+
+        //
+        // Single-value params
+        //
+
+// int
+        case GL_ARRAY_BUFFER_BINDING:
+        case GL_ELEMENT_ARRAY_BUFFER_BINDING: // XXX really?
+        case GL_CULL_FACE_MODE:
+        case GL_FRONT_FACE:
+        case GL_TEXTURE_BINDING_2D:
+        case GL_TEXTURE_BINDING_CUBE_MAP:
+        case GL_ACTIVE_TEXTURE:
+        case GL_STENCIL_WRITEMASK:
+        case GL_STENCIL_BACK_WRITEMASK:
+        case GL_DEPTH_CLEAR_VALUE:
+        case GL_STENCIL_CLEAR_VALUE:
+        case GL_STENCIL_FUNC:
+        case GL_STENCIL_VALUE_MASK:
+        case GL_STENCIL_REF:
+        case GL_STENCIL_FAIL:
+        case GL_STENCIL_PASS_DEPTH_FAIL:
+        case GL_STENCIL_PASS_DEPTH_PASS:
+        case GL_STENCIL_BACK_FUNC:
+        case GL_STENCIL_BACK_VALUE_MASK:
+        case GL_STENCIL_BACK_REF:
+        case GL_STENCIL_BACK_FAIL:
+        case GL_STENCIL_BACK_PASS_DEPTH_FAIL:
+        case GL_STENCIL_BACK_PASS_DEPTH_PASS:
+        case GL_DEPTH_FUNC:
+        case GL_BLEND_SRC_RGB:
+        case GL_BLEND_SRC_ALPHA:
+        case GL_BLEND_DST_RGB:
+        case GL_BLEND_DST_ALPHA:
+        case GL_BLEND_EQUATION_RGB:
+        case GL_BLEND_EQUATION_ALPHA:
+        //case GL_UNPACK_ALIGNMENT: // not supported
+        //case GL_PACK_ALIGNMENT: // not supported
+        case GL_CURRENT_PROGRAM:
+        case GL_GENERATE_MIPMAP_HINT:
+        case GL_SUBPIXEL_BITS:
+        case GL_MAX_TEXTURE_SIZE:
+        case GL_MAX_CUBE_MAP_TEXTURE_SIZE:
+        case GL_MAX_ELEMENTS_INDICES:
+        case GL_MAX_ELEMENTS_VERTICES:
+        case GL_SAMPLE_BUFFERS:
+        case GL_SAMPLES:
+        //case GL_COMPRESSED_TEXTURE_FORMATS:
+        //case GL_NUM_COMPRESSED_TEXTURE_FORMATS:
+        //case GL_SHADER_BINARY_FORMATS:
+        //case GL_NUM_SHADER_BINARY_FORMATS:
+        case GL_MAX_VERTEX_ATTRIBS:
+        case GL_MAX_VERTEX_UNIFORM_COMPONENTS:
+        case GL_MAX_VARYING_FLOATS:
+        case GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS:
+        case GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS:
+        case GL_MAX_TEXTURE_IMAGE_UNITS:
+        case GL_MAX_FRAGMENT_UNIFORM_COMPONENTS:
+        ////case GL_MAX_RENDERBUFFER_SIZE:
+        case GL_RED_BITS:
+        case GL_GREEN_BITS:
+        case GL_BLUE_BITS:
+        case GL_ALPHA_BITS:
+        case GL_DEPTH_BITS:
+        case GL_STENCIL_BITS:
+        //case GL_IMPLEMENTATION_COLOR_READ_TYPE:
+        //case GL_IMPLEMENTATION_COLOR_READ_FORMAT:
+        ////case GL_RENDERBUFFER_BINDING:
+        ////case GL_FRAMEBUFFER_BINDING:
+        {
+            PRInt32 iv;
+            glGetIntegerv(pname, &iv);
+            js.SetRetVal(iv);
+        }
+            break;
+
+// float
+        case GL_LINE_WIDTH:
+        case GL_POLYGON_OFFSET_FACTOR:
+        case GL_POLYGON_OFFSET_UNITS:
+        case GL_SAMPLE_COVERAGE_VALUE:
+        {
+            float fv;
+            glGetFloatv(pname, &fv);
+            js.SetRetVal((double) fv);
+        }
+            break;
+// bool
+        case GL_SAMPLE_COVERAGE_INVERT:
+        case GL_COLOR_WRITEMASK:
+        case GL_DEPTH_WRITEMASK:
+        ////case GL_SHADER_COMPILER: // pretty much must be true 
+        {
+            GLboolean bv;
+            glGetBooleanv(pname, &bv);
+            js.SetBoolRetVal(bv);
+        }
+            break;
+
+        //
+        // Complex values
+        //
+        case GL_DEPTH_RANGE: // 2 floats
+        case GL_ALIASED_POINT_SIZE_RANGE: // 2 floats
+        case GL_ALIASED_LINE_WIDTH_RANGE: // 2 floats
+        {
+            float fv[2];
+            glGetFloatv(pname, &fv[0]);
+            js.SetRetVal(fv, 2);
+        }
+            break;
+        
+        case GL_COLOR_CLEAR_VALUE: // 4 floats
+        case GL_BLEND_COLOR: // 4 floats
+        {
+            float fv[4];
+            glGetFloatv(pname, &fv[0]);
+            js.SetRetVal(fv, 4);
+        }
+            break;
+
+        case GL_MAX_VIEWPORT_DIMS: // 2 ints
+        {
+            PRInt32 iv[2];
+            glGetIntegerv(pname, &iv[0]);
+            js.SetRetVal(iv, 2);
+        }
+            break;
+
+        case GL_SCISSOR_BOX: // 4 ints
+        case GL_VIEWPORT: // 4 ints
+        {
+            PRInt32 iv[4];
+            glGetIntegerv(pname, &iv[0]);
+            js.SetRetVal(iv, 4);
+        }
+            break;
+
+        default:
+            return NS_ERROR_NOT_IMPLEMENTED;
+    }
+
+    return NS_OK;
+}
+
+NS_IMETHODIMP
+nsCanvasRenderingContextGLWeb20::GetBufferParameter(PRUint32 target, PRUint32 pname)
+{
+    NativeJSContext js;
+    if (NS_FAILED(js.error))
+        return js.error;
+
+    MakeContextCurrent();
+
+    switch (pname) {
+        case GL_BUFFER_SIZE:
+        case GL_BUFFER_USAGE:
+        case GL_BUFFER_ACCESS:
+        case GL_BUFFER_MAPPED:
+        {
+            PRInt32 iv;
+            glGetBufferParameteriv(target, pname, &iv);
+            js.SetRetVal(iv);
+        }
+            break;
+
+        default:
+            return NS_ERROR_NOT_IMPLEMENTED;
+    }
+
+    return NS_OK;
+}
+
+NS_IMETHODIMP
+nsCanvasRenderingContextGLWeb20::GenBuffers(PRUint32 n)
+{
+    NativeJSContext js;
+    if (NS_FAILED(js.error))
+        return js.error;
+
+    if (n == 0)
+        return NS_OK;
+
+    MakeContextCurrent();
+
+    nsAutoArrayPtr<PRUint32> buffers(new PRUint32[n]);
+    glGenBuffers(n, buffers.get());
+
+    nsAutoArrayPtr<jsval> jsvector(new jsval[n]);
+    for (PRUint32 i = 0; i < n; i++)
+        jsvector[i] = INT_TO_JSVAL(buffers[i]);
+
+    JSObject *obj = JS_NewArrayObject(js.ctx, n, jsvector);
+    jsval *retvalPtr;
+    js.ncc->GetRetValPtr(&retvalPtr);
+    *retvalPtr = OBJECT_TO_JSVAL(obj);
+    js.ncc->SetReturnValueWasSet(PR_TRUE);
+    
+    return NS_OK;
+}
+
+NS_IMETHODIMP
+nsCanvasRenderingContextGLWeb20::GenTextures(PRUint32 n)
+{
+    if (n == 0)
+        return NS_OK;
+
+    NativeJSContext js;
+    if (NS_FAILED(js.error))
+        return js.error;
+
+    MakeContextCurrent();
+
+    nsAutoArrayPtr<PRUint32> textures(new PRUint32[n]);
+    glGenTextures(n, textures.get());
+
+    nsAutoArrayPtr<jsval> jsvector(new jsval[n]);
+    for (PRUint32 i = 0; i < n; i++)
+        jsvector[i] = INT_TO_JSVAL(textures[i]);
+
+    JSObject *obj = JS_NewArrayObject(js.ctx, n, jsvector);
+    jsval *retvalPtr;
+    js.ncc->GetRetValPtr(&retvalPtr);
+    *retvalPtr = OBJECT_TO_JSVAL(obj);
+    js.ncc->SetReturnValueWasSet(PR_TRUE);
+    
+    return NS_OK;
+}
+
+NS_IMETHODIMP
+nsCanvasRenderingContextGLWeb20::GetError(PRUint32 *_retval)
+{
+    MakeContextCurrent();
+    *_retval = glGetError();
+    return NS_OK;
+}
+
+NS_IMETHODIMP
+nsCanvasRenderingContextGLWeb20::GetProgramParameter(PRUint32 program, PRUint32 pname)
+{
+    NativeJSContext js;
+    if (NS_FAILED(js.error))
+        return js.error;
+
+    MakeContextCurrent();
+
+    switch (pname) {
+        case GL_CURRENT_PROGRAM:
+        case GL_DELETE_STATUS:
+        case GL_LINK_STATUS:
+        case GL_VALIDATE_STATUS:
+        case GL_ATTACHED_SHADERS:
+        case GL_INFO_LOG_LENGTH:
+        case GL_ACTIVE_UNIFORMS:
+        case GL_ACTIVE_UNIFORM_MAX_LENGTH:
+        case GL_ACTIVE_ATTRIBUTES:
+        case GL_ACTIVE_ATTRIBUTE_MAX_LENGTH:
+        {
+            PRInt32 iv;
+            glGetProgramiv(program, pname, &iv);
+            js.SetRetVal(iv);
+        }
+            break;
+
+        default:
+            return NS_ERROR_NOT_IMPLEMENTED;
+    }
+
+    return NS_OK;
+}
+
+NS_IMETHODIMP
+nsCanvasRenderingContextGLWeb20::GetProgramInfoLog(PRUint32 program, char **retval)
+{
+    PRInt32 k;
+
+    MakeContextCurrent();
+
+    glGetProgramiv(program, GL_INFO_LOG_LENGTH, &k);
+    if (k == 0) {
+        *retval = nsnull;
+        return NS_OK;
+    }
+
+    char *s = (char *) PR_Malloc(k);
+
+    glGetProgramInfoLog(program, k, &k, s);
+
+    *retval = s;
+    return NS_OK;
+}
+
+/* void texParameter (); */
+NS_IMETHODIMP
+nsCanvasRenderingContextGLWeb20::TexParameter()
+{
+    NativeJSContext js;
+    if (NS_FAILED(js.error))
+        return js.error;
+
+    if (js.argc != 3)
+        return NS_ERROR_DOM_SYNTAX_ERR;
+
+    jsuint targetVal;
+    jsuint pnameVal;
+    if (!::JS_ValueToECMAUint32(js.ctx, js.argv[0], &targetVal) ||
+        !::JS_ValueToECMAUint32(js.ctx, js.argv[1], &pnameVal))
+        return NS_ERROR_DOM_SYNTAX_ERR;
+
+    if (targetVal != GL_TEXTURE_2D &&
+        (!GLEW_ARB_texture_rectangle || targetVal != GL_TEXTURE_RECTANGLE_ARB))
+    {
+        return NS_ERROR_DOM_SYNTAX_ERR;
+    }
+
+    MakeContextCurrent();
+    switch (pnameVal) {
+        case GL_TEXTURE_MIN_FILTER: {
+            jsuint ival;
+            if (!::JS_ValueToECMAUint32(js.ctx, js.argv[2], &ival) ||
+                (ival != GL_NEAREST &&
+                 ival != GL_LINEAR &&
+                 ival != GL_NEAREST_MIPMAP_NEAREST &&
+                 ival != GL_LINEAR_MIPMAP_NEAREST &&
+                 ival != GL_NEAREST_MIPMAP_LINEAR &&
+                 ival != GL_LINEAR_MIPMAP_LINEAR))
+                return NS_ERROR_DOM_SYNTAX_ERR;
+            glTexParameteri (targetVal, pnameVal, ival);
+        }
+            break;
+        case GL_TEXTURE_MAG_FILTER: {
+            jsuint ival;
+            if (!::JS_ValueToECMAUint32(js.ctx, js.argv[2], &ival) ||
+                (ival != GL_NEAREST &&
+                 ival != GL_LINEAR))
+                return NS_ERROR_DOM_SYNTAX_ERR;
+            glTexParameteri (targetVal, pnameVal, ival);
+        }
+            break;
+        case GL_TEXTURE_WRAP_S:
+        case GL_TEXTURE_WRAP_T: {
+            jsuint ival;
+            if (!::JS_ValueToECMAUint32(js.ctx, js.argv[2], &ival) ||
+                (ival != GL_CLAMP &&
+                 ival != GL_CLAMP_TO_EDGE &&
+                 ival != GL_REPEAT))
+                return NS_ERROR_DOM_SYNTAX_ERR;
+            glTexParameteri (targetVal, pnameVal, ival);
+        }
+            break;
+        case GL_GENERATE_MIPMAP: {
+            jsuint ival;
+            if (js.argv[2] == JSVAL_TRUE)
+                ival = 1;
+            else if (js.argv[2] == JSVAL_FALSE)
+                ival = 0;
+            else if (!::JS_ValueToECMAUint32(js.ctx, js.argv[2], &ival) ||
+                     (ival != 0 && ival != 1))
+                return NS_ERROR_DOM_SYNTAX_ERR;
+            glTexParameteri (targetVal, pnameVal, ival);
+        }
+            break;
+        case GL_TEXTURE_MAX_ANISOTROPY_EXT: {
+            if (GLEW_EXT_texture_filter_anisotropic) {
+                jsdouble dval;
+                if (!::JS_ValueToNumber(js.ctx, js.argv[2], &dval))
+                    return NS_ERROR_DOM_SYNTAX_ERR;
+                glTexParameterf (targetVal, pnameVal, (float) dval);
+            } else {
+                return NS_ERROR_NOT_IMPLEMENTED;
+            }
+        }
+            break;
+        default:
+            return NS_ERROR_DOM_SYNTAX_ERR;
+    }
+
+    return NS_OK;
+}
+
+/* void getTexParameter (); */
+NS_IMETHODIMP
+nsCanvasRenderingContextGLWeb20::GetTexParameter(PRUint32 target, PRUint32 pname)
+{
+    NativeJSContext js;
+    if (NS_FAILED(js.error))
+        return js.error;
+
+    MakeContextCurrent();
+
+    switch (pname) {
+        case GL_TEXTURE_MIN_FILTER:
+        case GL_TEXTURE_MAG_FILTER:
+        case GL_TEXTURE_WRAP_S:
+        case GL_TEXTURE_WRAP_T:
+        {
+            PRInt32 iv;
+            glGetTexParameteriv(target, pname, &iv);
+            js.SetRetVal(iv);
+        }
+            break;
+
+        default:
+            return NS_ERROR_NOT_IMPLEMENTED;
+    }
+
+    return NS_OK;
+}
+
+NS_IMETHODIMP
+nsCanvasRenderingContextGLWeb20::GetUniform(PRUint32 program, PRUint32 location)
+{
+    return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+NS_IMETHODIMP
+nsCanvasRenderingContextGLWeb20::GetUniformLocation(PRUint32 program, const char *name, PRInt32 *retval)
+{
+    MakeContextCurrent();
+    *retval = glGetUniformLocation(program, name);
+    return NS_OK;
+}
+
+NS_IMETHODIMP
+nsCanvasRenderingContextGLWeb20::GetVertexAttrib(PRUint32 index, PRUint32 pname)
+{
+    // ...
+    return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+NS_IMETHODIMP
+nsCanvasRenderingContextGLWeb20::Hint(PRUint32 target, PRUint32 mode)
+{
+    return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+NS_IMETHODIMP
+nsCanvasRenderingContextGLWeb20::IsBuffer(PRUint32 k, PRBool *retval)
+{
+    MakeContextCurrent();
+    *retval = glIsBuffer(k);
+    return NS_OK;
+}
+
+NS_IMETHODIMP
+nsCanvasRenderingContextGLWeb20::IsEnabled(PRUint32 k, PRBool *retval)
+{
+    MakeContextCurrent();
+    *retval = glIsEnabled(k);
+    return NS_OK;
+}
+
+NS_IMETHODIMP
+nsCanvasRenderingContextGLWeb20::IsProgram(PRUint32 k, PRBool *retval)
+{
+    MakeContextCurrent();
+    *retval = glIsProgram(k);
+    return NS_OK;
+}
+
+NS_IMETHODIMP
+nsCanvasRenderingContextGLWeb20::IsShader(PRUint32 k, PRBool *retval)
+{
+    MakeContextCurrent();
+    *retval = glIsShader(k);
+    return NS_OK;
+}
+
+NS_IMETHODIMP
+nsCanvasRenderingContextGLWeb20::IsTexture(PRUint32 k, PRBool *retval)
+{
+    MakeContextCurrent();
+    *retval = glIsTexture(k);
+    return NS_OK;
+}
+
+GL_SAME_METHOD_1(LineWidth, LineWidth, float)
+
+GL_SAME_METHOD_1(LinkProgram, LinkProgram, PRUint32)
+
+GL_SAME_METHOD_2(PolygonOffset, PolygonOffset, float, float)
+
+GL_SAME_METHOD_2(SampleCoverage, SampleCoverage, float, PRBool)
+
+GL_SAME_METHOD_4(Scissor, Scissor, PRInt32, PRInt32, PRInt32, PRInt32)
+
+GL_SAME_METHOD_3(StencilFunc, StencilFunc, PRUint32, PRInt32, PRUint32)
+
+GL_SAME_METHOD_4(StencilFuncSeparate, StencilFuncSeparate, PRUint32, PRUint32, PRInt32, PRUint32)
+
+GL_SAME_METHOD_1(StencilMask, StencilMask, PRUint32)
+
+GL_SAME_METHOD_2(StencilMaskSeparate, StencilMaskSeparate, PRUint32, PRUint32)
+
+GL_SAME_METHOD_3(StencilOp, StencilOp, PRUint32, PRUint32, PRUint32)
+
+GL_SAME_METHOD_4(StencilOpSeparate, StencilOpSeparate, PRUint32, PRUint32, PRUint32, PRUint32)
+
+NS_IMETHODIMP
+nsCanvasRenderingContextGLWeb20::TexImage2DHTML(PRUint32 target, nsIDOMHTMLElement *imageOrCanvas)
+{
+    nsresult rv;
+    cairo_surface_t *cairo_surf = nsnull;
+    PRUint8 *image_data = nsnull, *local_image_data = nsnull;
+    PRInt32 width, height;
+    nsCOMPtr<nsIURI> element_uri;
+    PRBool force_write_only = PR_FALSE;
+
+    rv = CairoSurfaceFromElement(imageOrCanvas, &cairo_surf, &image_data,
+                                 &width, &height, getter_AddRefs(element_uri), &force_write_only);
+    if (NS_FAILED(rv))
+        return rv;
+
+    DoDrawImageSecurityCheck(element_uri, force_write_only);
+
+    if (target == GL_TEXTURE_2D) {
+        if ((width & (width-1)) != 0 ||
+            (height & (height-1)) != 0)
+            return NS_ERROR_INVALID_ARG;
+    } else if (GLEW_ARB_texture_rectangle && target == GL_TEXTURE_RECTANGLE_ARB) {
+        if (width == 0 || height == 0)
+            return NS_ERROR_INVALID_ARG;
+    } else {
+        return NS_ERROR_INVALID_ARG;
+    }
+
+    if (!image_data) {
+        local_image_data = (PRUint8*) PR_Malloc(width * height * 4);
+        if (!local_image_data)
+            return NS_ERROR_FAILURE;
+
+        cairo_surface_t *tmp = cairo_image_surface_create_for_data (local_image_data,
+                                                                    CAIRO_FORMAT_ARGB32,
+                                                                    width, height, width * 4);
+        if (!tmp) {
+            PR_Free(local_image_data);
+            return NS_ERROR_FAILURE;
+        }
+
+        cairo_t *tmp_cr = cairo_create (tmp);
+        cairo_set_source_surface (tmp_cr, cairo_surf, 0, 0);
+        cairo_set_operator (tmp_cr, CAIRO_OPERATOR_SOURCE);
+        cairo_paint (tmp_cr);
+        cairo_destroy (tmp_cr);
+        cairo_surface_destroy (tmp);
+
+        image_data = local_image_data;
+    }
+
+    // Er, I can do this with glPixelStore, no?
+    // the incoming data will /always/ be
+    // (A << 24) | (R << 16) | (G << 8) | B
+    // in a native-endian 32-bit int.
+    PRUint8* ptr = image_data;
+    for (int j = 0; j < height; j++) {
+        for (int i = 0; i < width; i++) {
+#ifdef IS_LITTLE_ENDIAN
+            PRUint8 b = ptr[0];
+            PRUint8 g = ptr[1];
+            PRUint8 r = ptr[2];
+            PRUint8 a = ptr[3];
+#else
+            PRUint8 a = ptr[0];
+            PRUint8 r = ptr[1];
+            PRUint8 g = ptr[2];
+            PRUint8 b = ptr[3];
+#endif
+            ptr[0] = r;
+            ptr[1] = g;
+            ptr[2] = b;
+            ptr[3] = a;
+            ptr += 4;
+        }
+    }
+
+    MakeContextCurrent();
+
+    glTexImage2D(target, 0, 4, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, image_data);
+
+    if (local_image_data)
+        PR_Free(local_image_data);
+
+    return NS_OK;
+}
+
+// two usages:
+//  uniformi(idx, [a, b, c, d])
+//  uniformi(idx, elcount, count, [......])
+NS_IMETHODIMP
+nsCanvasRenderingContextGLWeb20::Uniformi()
+{
+    NativeJSContext js;
+    if (NS_FAILED(js.error))
+        return js.error;
+
+    if (js.argc != 2 && js.argc != 4)
+        return NS_ERROR_DOM_SYNTAX_ERR;
+
+    int32 uniformIndex;
+    jsuint elementCount = 0, uniformCount = 1;
+
+    if (!::JS_ValueToInt32(js.ctx, js.argv[0], &uniformIndex))
+        return NS_ERROR_DOM_SYNTAX_ERR;
+
+    if (js.argc == 4 &&
+        !::JS_ValueToECMAUint32(js.ctx, js.argv[1], &elementCount) &&
+        !::JS_ValueToECMAUint32(js.ctx, js.argv[2], &uniformCount))
+        return NS_ERROR_DOM_SYNTAX_ERR;
+
+    JSObject *arrayObj;
+    jsuint arrayLen;
+    if (!JSValToJSArrayAndLength(js.ctx, js.argv[js.argc-1], &arrayObj, &arrayLen))
+        return NS_ERROR_DOM_SYNTAX_ERR;
+
+    SimpleBuffer sbuffer;
+    nsresult rv = JSArrayToSimpleBuffer(sbuffer, GL_INT, 1, js.ctx, arrayObj, arrayLen);
+    if (NS_FAILED(rv))
+        return NS_ERROR_DOM_SYNTAX_ERR;
+
+    if (js.argc == 2) {
+        elementCount = arrayLen;
+        if (elementCount < 1 || elementCount > 4)
+            return NS_ERROR_DOM_SYNTAX_ERR;
+    }
+
+    if (arrayLen < elementCount * uniformCount)
+        return NS_ERROR_DOM_SYNTAX_ERR;
+
+    MakeContextCurrent();
+    switch (elementCount) {
+        case 1:
+            glUniform1iv (uniformIndex, uniformCount, (GLint*) sbuffer.data);
+            break;
+        case 2:
+            glUniform2iv (uniformIndex, uniformCount, (GLint*) sbuffer.data);
+            break;
+        case 3:
+            glUniform3iv (uniformIndex, uniformCount, (GLint*) sbuffer.data);
+            break;
+        case 4:
+            glUniform4iv (uniformIndex, uniformCount, (GLint*) sbuffer.data);
+            break;
+    }
+
+    return NS_OK;
+}
+
+// two usages:
+//  uniformf(idx, [a, b, c, d])
+//  uniformf(idx, elcount, count, [......])
+NS_IMETHODIMP
+nsCanvasRenderingContextGLWeb20::Uniformf()
+{
+    NativeJSContext js;
+    if (NS_FAILED(js.error))
+        return js.error;
+
+    if (js.argc != 2 && js.argc != 4)
+        return NS_ERROR_DOM_SYNTAX_ERR;
+
+    int32 uniformIndex;
+    jsuint elementCount = 0, uniformCount = 1;
+
+    if (!::JS_ValueToInt32(js.ctx, js.argv[0], &uniformIndex))
+        return NS_ERROR_DOM_SYNTAX_ERR;
+
+    if (js.argc == 4 &&
+        !::JS_ValueToECMAUint32(js.ctx, js.argv[1], &elementCount) &&
+        !::JS_ValueToECMAUint32(js.ctx, js.argv[2], &uniformCount))
+        return NS_ERROR_DOM_SYNTAX_ERR;
+
+    JSObject *arrayObj;
+    jsuint arrayLen;
+    if (!JSValToJSArrayAndLength(js.ctx, js.argv[js.argc-1], &arrayObj, &arrayLen))
+        return NS_ERROR_DOM_SYNTAX_ERR;
+
+    SimpleBuffer sbuffer;
+    nsresult rv = JSArrayToSimpleBuffer(sbuffer, GL_FLOAT, 1, js.ctx, arrayObj, arrayLen);
+    if (NS_FAILED(rv))
+        return NS_ERROR_DOM_SYNTAX_ERR;
+
+    if (js.argc == 2) {
+        elementCount = arrayLen;
+        if (elementCount < 1 || elementCount > 4)
+            return NS_ERROR_DOM_SYNTAX_ERR;
+    }
+
+    if (arrayLen < elementCount * uniformCount)
+        return NS_ERROR_DOM_SYNTAX_ERR;
+
+    MakeContextCurrent();
+    switch (elementCount) {
+        case 1:
+            glUniform1fv (uniformIndex, uniformCount, (float*) sbuffer.data);
+            break;
+        case 2:
+            glUniform2fv (uniformIndex, uniformCount, (float*) sbuffer.data);
+            break;
+        case 3:
+            glUniform3fv (uniformIndex, uniformCount, (float*) sbuffer.data);
+            break;
+        case 4:
+            glUniform4fv (uniformIndex, uniformCount, (float*) sbuffer.data);
+            break;
+    }
+
+    return NS_OK;
+}
+
+// two usages:
+//  uniformMatrix(idx, [4, 9, 16])
+//  uniformMatrix(idx, elcount, count, [ 4*count, 9*count, 16*count ]
+NS_IMETHODIMP
+nsCanvasRenderingContextGLWeb20::UniformMatrix()
+{
+    NativeJSContext js;
+    if (NS_FAILED(js.error))
+        return js.error;
+
+    if (js.argc != 2 && js.argc != 4)
+        return NS_ERROR_DOM_SYNTAX_ERR;
+
+    int32 uniformIndex;
+    jsuint elementCount = 0, uniformCount = 1;
+
+    if (!::JS_ValueToInt32(js.ctx, js.argv[0], &uniformIndex))
+        return NS_ERROR_DOM_SYNTAX_ERR;
+
+    if (js.argc == 4 &&
+        !::JS_ValueToECMAUint32(js.ctx, js.argv[1], &elementCount) &&
+        !::JS_ValueToECMAUint32(js.ctx, js.argv[2], &uniformCount))
+        return NS_ERROR_DOM_SYNTAX_ERR;
+
+    JSObject *arrayObj;
+    jsuint arrayLen;
+    if (!JSValToJSArrayAndLength(js.ctx, js.argv[js.argc-1], &arrayObj, &arrayLen))
+        return NS_ERROR_DOM_SYNTAX_ERR;
+
+    SimpleBuffer sbuffer;
+    nsresult rv = JSArrayToSimpleBuffer(sbuffer, GL_FLOAT, 1, js.ctx, arrayObj, arrayLen);
+    if (NS_FAILED(rv))
+        return NS_ERROR_DOM_SYNTAX_ERR;
+
+    if (js.argc == 2) {
+        if (arrayLen == 4)
+            elementCount = 2;
+        else if (arrayLen == 9)
+            elementCount = 3;
+        else if (arrayLen == 16)
+            elementCount = 4;
+        else
+            return NS_ERROR_DOM_SYNTAX_ERR;
+    }
+
+    if (arrayLen < elementCount * uniformCount)
+        return NS_ERROR_DOM_SYNTAX_ERR;
+
+    MakeContextCurrent();
+    switch (elementCount) {
+        case 2:
+            glUniformMatrix2fv (uniformIndex, uniformCount, PR_FALSE, (float*) sbuffer.data);
+            break;
+        case 3:
+            glUniformMatrix3fv (uniformIndex, uniformCount, PR_FALSE, (float*) sbuffer.data);
+            break;
+        case 4:
+            glUniformMatrix4fv (uniformIndex, uniformCount, PR_FALSE, (float*) sbuffer.data);
+            break;
+    }
+
+    return NS_OK;
+}
+
+GL_SAME_METHOD_1(UseProgram, UseProgram, PRUint32)
+
+GL_SAME_METHOD_1(ValidateProgram, ValidateProgram, PRUint32)
+
+NS_IMETHODIMP
+nsCanvasRenderingContextGLWeb20::VertexAttrib()
+{
+    return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+GL_SAME_METHOD_4(Viewport, Viewport, PRInt32, PRInt32, PRInt32, PRInt32)
+
+GL_SAME_METHOD_1(CompileShader, CompileShader, PRUint32)
+
+NS_IMETHODIMP
+nsCanvasRenderingContextGLWeb20::GetShaderParameter(PRUint32 shader, PRUint32 pname)
+{
+    NativeJSContext js;
+    if (NS_FAILED(js.error))
+        return js.error;
+
+    MakeContextCurrent();
+
+    switch (pname) {
+        case GL_SHADER_TYPE:
+        case GL_DELETE_STATUS:
+        case GL_COMPILE_STATUS:
+        case GL_INFO_LOG_LENGTH:
+        case GL_SHADER_SOURCE_LENGTH:
+        {
+            PRInt32 iv;
+            glGetShaderiv(shader, pname, &iv);
+            js.SetRetVal(iv);
+        }
+            break;
+
+        default:
+            return NS_ERROR_NOT_IMPLEMENTED;
+    }
+
+    return NS_OK;
+}
+
+NS_IMETHODIMP
+nsCanvasRenderingContextGLWeb20::GetShaderInfoLog(PRUint32 shader, char **retval)
+{
+    PRInt32 k;
+
+    MakeContextCurrent();
+
+    glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &k);
+
+    char *s = (char *) PR_Malloc(k);
+
+    glGetShaderInfoLog(shader, k, &k, s);
+
+    *retval = s;
+    return NS_OK;
+}
+
+NS_IMETHODIMP
+nsCanvasRenderingContextGLWeb20::GetShaderSource(PRUint32 shader, char **retval)
+{
+    return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+NS_IMETHODIMP
+nsCanvasRenderingContextGLWeb20::ShaderSource(PRUint32 shader, const char *source)
+{
+    MakeContextCurrent();
+
+    glShaderSource(shader, 1, &source, NULL);
+    return NS_OK;
+}
+
+NS_IMETHODIMP
+nsCanvasRenderingContextGLWeb20::SwapBuffers()
+{
+    return DoSwapBuffers();
+}
+
+NS_IMETHODIMP
+nsCanvasRenderingContextGLWeb20::VertexAttribPointer()
+{
+    NativeJSContext js;
+    if (NS_FAILED(js.error))
+        return js.error;
+
+    nsRefPtr<CanvasGLBuffer> newBuffer;
+    nsresult rv;
+
+    jsuint vertexAttribIndex;
+
+    if (js.argc == 2) {
+        if (!::JS_ValueToECMAUint32(js.ctx, js.argv[0], &vertexAttribIndex))
+            return NS_ERROR_DOM_SYNTAX_ERR;
+
+        nsCOMPtr<nsICanvasRenderingContextGLBuffer> bufferBase;
+        rv = JSValToSpecificInterface(js.ctx, js.argv[1], (nsICanvasRenderingContextGLBuffer**) getter_AddRefs(bufferBase));
+        if (NS_FAILED(rv))
+            return rv;
+
+        newBuffer = (CanvasGLBuffer*) bufferBase.get();
+
+        if (newBuffer->mType != GL_SHORT &&
+            newBuffer->mType != GL_FLOAT)
+            return NS_ERROR_DOM_SYNTAX_ERR;
+
+        if (newBuffer->mSize < 2 || newBuffer->mSize > 4)
+            return NS_ERROR_DOM_SYNTAX_ERR;
+
+    } else if (js.argc == 4) {
+        jsuint sizeParam;
+        jsuint typeParam;
+
+        JSObject *arrayObj;
+        jsuint arrayLen;
+
+        if (!::JS_ValueToECMAUint32(js.ctx, js.argv[0], &vertexAttribIndex) ||
+            !::JS_ValueToECMAUint32(js.ctx, js.argv[1], &sizeParam) ||
+            !::JS_ValueToECMAUint32(js.ctx, js.argv[2], &typeParam) ||
+            !JSValToJSArrayAndLength(js.ctx, js.argv[3], &arrayObj, &arrayLen))
+        {
+            return NS_ERROR_DOM_SYNTAX_ERR;
+        }
+
+        if (typeParam != GL_SHORT &&
+            typeParam != GL_FLOAT &&
+            (sizeParam < 2 || sizeParam > 4))
+            return NS_ERROR_DOM_SYNTAX_ERR;
+
+        newBuffer = new CanvasGLBuffer(this);
+        if (!newBuffer)
+            return NS_ERROR_OUT_OF_MEMORY;
+
+        rv = newBuffer->Init (GL_STATIC_DRAW, sizeParam, typeParam, js.ctx, arrayObj, arrayLen);
+        if (NS_FAILED(rv))
+            return rv;
+    } else {
+        return NS_ERROR_DOM_SYNTAX_ERR;
+    }
+
+    MakeContextCurrent();
+    glVertexAttribPointer(vertexAttribIndex,
+                          newBuffer->GetSimpleBuffer().sizePerVertex,
+                          newBuffer->GetSimpleBuffer().type,
+                          0,
+                          0,
+                          newBuffer->GetSimpleBuffer().data);
+    return NS_OK;
+}
+
+PRBool
+nsCanvasRenderingContextGLWeb20::ValidateGL()
+{
+    // make sure that the opengl stuff that we need is supported
+    if (!GLEW_VERSION_2_0)
+        return PR_FALSE;
+
+    return PR_TRUE;
+}