servo: Merge #20525 - More WebGL improvements (from servo:webgl2); r=emilio
authorAnthony Ramine <n.oxyde@gmail.com>
Wed, 04 Apr 2018 07:19:26 -0400
changeset 411655 96f5011b881fe0d9bd0529a43f9812238c6efd9f
parent 411654 6b052fb6d3289aec5ee9805eb068687b9a2cc7e8
child 411656 fa109105e4eadb31fe8a1bedf6f644fdc290e897
push id33764
push usercsabou@mozilla.com
push dateWed, 04 Apr 2018 17:53:18 +0000
treeherdermozilla-central@90eb45ff0a64 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersemilio
milestone61.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
servo: Merge #20525 - More WebGL improvements (from servo:webgl2); r=emilio Source-Repo: https://github.com/servo/servo Source-Revision: e06f0d32d0c3973d460a3035d2adfea298c8e5fe
servo/components/script/dom/macros.rs
servo/components/script/dom/webgl2renderingcontext.rs
servo/components/script/dom/webglbuffer.rs
servo/components/script/dom/webglrenderingcontext.rs
servo/components/script/dom/webidls/WebGL2RenderingContext.webidl
servo/components/script/dom/webidls/WebGLRenderingContext.webidl
--- a/servo/components/script/dom/macros.rs
+++ b/servo/components/script/dom/macros.rs
@@ -609,8 +609,23 @@ macro_rules! impl_performance_entry_stru
                        start_time: f64,
                        duration: f64) -> DomRoot<$struct> {
                 let entry = $struct::new_inherited(name, start_time, duration);
                 reflect_dom_object(Box::new(entry), global, $binding::Wrap)
             }
         }
     );
 );
+
+macro_rules! handle_potential_webgl_error {
+    ($context:expr, $call:expr, $return_on_error:expr) => {
+        match $call {
+            Ok(ret) => ret,
+            Err(error) => {
+                $context.webgl_error(error);
+                $return_on_error
+            }
+        }
+    };
+    ($context:expr, $call:expr) => {
+        handle_potential_webgl_error!($context, $call, ());
+    };
+}
--- a/servo/components/script/dom/webgl2renderingcontext.rs
+++ b/servo/components/script/dom/webgl2renderingcontext.rs
@@ -236,17 +236,17 @@ impl WebGL2RenderingContextMethods for W
     }
 
     /// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.5
     fn BufferData_(&self, target: u32, size: i64, usage: u32) -> Fallible<()> {
         self.base.BufferData_(target, size, usage)
     }
 
     /// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.5
-    fn BufferSubData(&self, target: u32, offset: i64, data: Option<ArrayBufferViewOrArrayBuffer>) {
+    fn BufferSubData(&self, target: u32, offset: i64, data: ArrayBufferViewOrArrayBuffer) {
         self.base.BufferSubData(target, offset, data)
     }
 
     /// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.8
     fn CompressedTexImage2D(&self, target: u32, level: i32, internal_format: u32,
                             width: i32, height: i32, border: i32,
                             pixels: CustomAutoRooterGuard<ArrayBufferView>) {
         self.base.CompressedTexImage2D(target, level, internal_format, width, height, border, pixels)
--- a/servo/components/script/dom/webglbuffer.rs
+++ b/servo/components/script/dom/webglbuffer.rs
@@ -2,16 +2,17 @@
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 // https://www.khronos.org/registry/webgl/specs/latest/1.0/webgl.idl
 use canvas_traits::webgl::{WebGLBufferId, WebGLCommand, WebGLError, WebGLMsgSender, WebGLResult, WebGLVertexArrayId};
 use canvas_traits::webgl::webgl_channel;
 use dom::bindings::cell::DomRefCell;
 use dom::bindings::codegen::Bindings::WebGLBufferBinding;
+use dom::bindings::codegen::Bindings::WebGLRenderingContextBinding::WebGLRenderingContextConstants;
 use dom::bindings::reflector::reflect_dom_object;
 use dom::bindings::root::DomRoot;
 use dom::webglobject::WebGLObject;
 use dom::window::Window;
 use dom_struct::dom_struct;
 use std::cell::Cell;
 use std::collections::HashSet;
 
@@ -81,28 +82,35 @@ impl WebGLBuffer {
             self.target.set(Some(target));
         }
         let msg = WebGLCommand::BindBuffer(target, Some(self.id));
         self.renderer.send(msg).unwrap();
 
         Ok(())
     }
 
-    pub fn buffer_data(&self, target: u32, data: &[u8], usage: u32) -> WebGLResult<()> {
+    pub fn buffer_data<T>(&self, target: u32, data: T, usage: u32) -> WebGLResult<()>
+    where
+        T: Into<Vec<u8>>,
+    {
+        match usage {
+            WebGLRenderingContextConstants::STREAM_DRAW |
+            WebGLRenderingContextConstants::STATIC_DRAW |
+            WebGLRenderingContextConstants::DYNAMIC_DRAW => (),
+            _ => return Err(WebGLError::InvalidEnum),
+        }
+
         if let Some(previous_target) = self.target.get() {
             if target != previous_target {
                 return Err(WebGLError::InvalidOperation);
             }
         }
+        let data = data.into();
         self.capacity.set(data.len());
-        self.renderer.send(WebGLCommand::BufferData(
-            target,
-            data.to_vec().into(),
-            usage,
-        )).unwrap();
+        self.renderer.send(WebGLCommand::BufferData(target, data.into(), usage)).unwrap();
 
         Ok(())
     }
 
     pub fn capacity(&self) -> usize {
         self.capacity.get()
     }
 
--- a/servo/components/script/dom/webglrenderingcontext.rs
+++ b/servo/components/script/dom/webglrenderingcontext.rs
@@ -1,16 +1,17 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 use byteorder::{NativeEndian, ReadBytesExt, WriteBytesExt};
 use canvas_traits::canvas::{byte_swap, multiply_u8_pixel};
-use canvas_traits::webgl::{WebGLContextShareMode, WebGLCommand, WebGLError, WebGLVersion, WebGLSLVersion};
-use canvas_traits::webgl::{WebGLFramebufferBindingRequest, WebGLMsg, WebGLMsgSender, WebGLParameter, WebVRCommand};
+use canvas_traits::webgl::{WebGLCommand, WebGLContextShareMode, WebGLError};
+use canvas_traits::webgl::{WebGLFramebufferBindingRequest, WebGLMsg, WebGLMsgSender};
+use canvas_traits::webgl::{WebGLParameter, WebGLResult, WebGLSLVersion, WebGLVersion, WebVRCommand};
 use canvas_traits::webgl::DOMToTextureCommand;
 use canvas_traits::webgl::WebGLError::*;
 use canvas_traits::webgl::webgl_channel;
 use dom::bindings::cell::DomRefCell;
 use dom::bindings::codegen::Bindings::WebGL2RenderingContextBinding::WebGL2RenderingContextConstants as WebGL2Constants;
 use dom::bindings::codegen::Bindings::WebGLRenderingContextBinding::{self, WebGLContextAttributes};
 use dom::bindings::codegen::Bindings::WebGLRenderingContextBinding::WebGLRenderingContextConstants as constants;
 use dom::bindings::codegen::Bindings::WebGLRenderingContextBinding::WebGLRenderingContextMethods;
@@ -62,31 +63,16 @@ use std::cell::{Cell, Ref};
 use std::cmp;
 use std::iter::FromIterator;
 use std::ptr::NonNull;
 use webrender_api;
 
 type ImagePixelResult = Result<(Vec<u8>, Size2D<i32>, bool), ()>;
 pub const MAX_UNIFORM_AND_ATTRIBUTE_LEN: usize = 256;
 
-macro_rules! handle_potential_webgl_error {
-    ($context:ident, $call:expr, $return_on_error:expr) => {
-        match $call {
-            Ok(ret) => ret,
-            Err(error) => {
-                $context.webgl_error(error);
-                $return_on_error
-            }
-        }
-    };
-    ($context:ident, $call:expr) => {
-        handle_potential_webgl_error!($context, $call, ());
-    };
-}
-
 // From the GLES 2.0.25 spec, page 85:
 //
 //     "If a texture that is currently bound to one of the targets
 //      TEXTURE_2D, or TEXTURE_CUBE_MAP is deleted, it is as though
 //      BindTexture had been executed with the same target and texture
 //      zero."
 //
 // and similar text occurs for other object types.
@@ -1190,16 +1176,24 @@ impl WebGLRenderingContext {
             width as i32,
             height as i32,
             constants::RGBA,
             constants::UNSIGNED_BYTE,
             sender,
         ));
         Some(receiver.recv().unwrap().into())
     }
+
+    pub fn bound_buffer(&self, target: u32) -> WebGLResult<Option<DomRoot<WebGLBuffer>>> {
+        match target {
+            constants::ARRAY_BUFFER => Ok(self.bound_buffer_array.get()),
+            constants::ELEMENT_ARRAY_BUFFER => Ok(self.bound_buffer_element_array.get()),
+            _ => Err(WebGLError::InvalidEnum),
+        }
+    }
 }
 
 impl Drop for WebGLRenderingContext {
     fn drop(&mut self) {
         self.webgl_sender.send_remove().unwrap();
     }
 }
 
@@ -1251,24 +1245,18 @@ impl WebGLRenderingContextMethods for We
     #[allow(unsafe_code)]
     // https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.5
     unsafe fn GetBufferParameter(
         &self,
         _cx: *mut JSContext,
         target: u32,
         parameter: u32,
     ) -> JSVal {
-        let buffer = match target {
-            constants::ARRAY_BUFFER => self.bound_buffer_array.get(),
-            constants::ELEMENT_ARRAY_BUFFER => self.bound_buffer_element_array.get(),
-            _ => {
-                self.webgl_error(InvalidEnum);
-                return NullValue();
-            }
-        };
+        let buffer = handle_potential_webgl_error!(self, self.bound_buffer(target), return NullValue());
+
         match parameter {
             constants::BUFFER_SIZE | constants::BUFFER_USAGE => {},
             _ => {
                 self.webgl_error(InvalidEnum);
                 return NullValue();
             }
         }
         let buffer = match buffer {
@@ -1688,87 +1676,54 @@ impl WebGLRenderingContextMethods for We
         }
 
         typedarray!(in(cx) let array_buffer: ArrayBuffer = data);
         let data_vec = match array_buffer {
             Ok(mut data) => data.to_vec(),
             Err(_) => fallible_array_buffer_view_to_vec(cx, data)?,
         };
 
-        let bound_buffer = match target {
-            constants::ARRAY_BUFFER => self.bound_buffer_array.get(),
-            constants::ELEMENT_ARRAY_BUFFER => self.bound_buffer_element_array.get(),
-            _ => return Ok(self.webgl_error(InvalidEnum)),
-        };
-
+        let bound_buffer = handle_potential_webgl_error!(self, self.bound_buffer(target), return Ok(()));
         let bound_buffer = match bound_buffer {
             Some(bound_buffer) => bound_buffer,
-            None => return Ok(self.webgl_error(InvalidValue)),
+            None => return Ok(self.webgl_error(InvalidOperation)),
         };
 
-        match usage {
-            constants::STREAM_DRAW |
-            constants::STATIC_DRAW |
-            constants::DYNAMIC_DRAW => (),
-            _ => return Ok(self.webgl_error(InvalidEnum)),
-        }
-
-        handle_potential_webgl_error!(self, bound_buffer.buffer_data(target, &data_vec, usage));
-
+        handle_potential_webgl_error!(self, bound_buffer.buffer_data(target, data_vec, usage));
         Ok(())
     }
 
     // https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.5
     fn BufferData_(&self, target: u32, size: i64, usage: u32) -> ErrorResult {
-        let bound_buffer = match target {
-            constants::ARRAY_BUFFER => self.bound_buffer_array.get(),
-            constants::ELEMENT_ARRAY_BUFFER => self.bound_buffer_element_array.get(),
-            _ => return Ok(self.webgl_error(InvalidEnum)),
-        };
-
+        let bound_buffer = handle_potential_webgl_error!(self, self.bound_buffer(target), return Ok(()));
         let bound_buffer = match bound_buffer {
             Some(bound_buffer) => bound_buffer,
-            None => return Ok(self.webgl_error(InvalidValue)),
+            None => return Ok(self.webgl_error(InvalidOperation)),
         };
 
         if size < 0 {
             return Ok(self.webgl_error(InvalidValue));
         }
 
-        match usage {
-            constants::STREAM_DRAW |
-            constants::STATIC_DRAW |
-            constants::DYNAMIC_DRAW => (),
-            _ => return Ok(self.webgl_error(InvalidEnum)),
-        }
-
         // FIXME: Allocating a buffer based on user-requested size is
         // not great, but we don't have a fallible allocation to try.
         let data = vec![0u8; size as usize];
-        handle_potential_webgl_error!(self, bound_buffer.buffer_data(target, &data, usage));
-
+        handle_potential_webgl_error!(self, bound_buffer.buffer_data(target, data, usage));
         Ok(())
     }
 
     // https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.5
-    fn BufferSubData(&self, target: u32, offset: i64, data: Option<ArrayBufferViewOrArrayBuffer>) {
+    fn BufferSubData(&self, target: u32, offset: i64, data: ArrayBufferViewOrArrayBuffer) {
         let data_vec = match data {
             // Typed array is rooted, so we can safely temporarily retrieve its slice
-            Some(ArrayBufferViewOrArrayBuffer::ArrayBuffer(mut inner)) => inner.to_vec(),
-            Some(ArrayBufferViewOrArrayBuffer::ArrayBufferView(mut inner)) => inner.to_vec(),
-            // Spec: If data is null then an INVALID_VALUE error is generated.
-            None => return self.webgl_error(InvalidValue),
+            ArrayBufferViewOrArrayBuffer::ArrayBuffer(mut inner) => inner.to_vec(),
+            ArrayBufferViewOrArrayBuffer::ArrayBufferView(mut inner) => inner.to_vec(),
         };
 
-        let bound_buffer = match target {
-            constants::ARRAY_BUFFER => self.bound_buffer_array.get(),
-            constants::ELEMENT_ARRAY_BUFFER => self.bound_buffer_element_array.get(),
-            _ => return self.webgl_error(InvalidEnum),
-        };
-
+        let bound_buffer = handle_potential_webgl_error!(self, self.bound_buffer(target), return);
         let bound_buffer = match bound_buffer {
             Some(bound_buffer) => bound_buffer,
             None => return self.webgl_error(InvalidOperation),
         };
 
         if offset < 0 {
             return self.webgl_error(InvalidValue);
         }
--- a/servo/components/script/dom/webidls/WebGL2RenderingContext.webidl
+++ b/servo/components/script/dom/webidls/WebGL2RenderingContext.webidl
@@ -174,16 +174,17 @@ interface WebGL2RenderingContextBase
   const GLenum FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE         = 0x8211;
   const GLenum FRAMEBUFFER_ATTACHMENT_RED_SIZE               = 0x8212;
   const GLenum FRAMEBUFFER_ATTACHMENT_GREEN_SIZE             = 0x8213;
   const GLenum FRAMEBUFFER_ATTACHMENT_BLUE_SIZE              = 0x8214;
   const GLenum FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE             = 0x8215;
   const GLenum FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE             = 0x8216;
   const GLenum FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE           = 0x8217;
   const GLenum FRAMEBUFFER_DEFAULT                           = 0x8218;
+  // BUG: https://github.com/KhronosGroup/WebGL/issues/2216
   // const GLenum DEPTH_STENCIL_ATTACHMENT                      = 0x821A;
   // const GLenum DEPTH_STENCIL                                 = 0x84F9;
   const GLenum UNSIGNED_INT_24_8                             = 0x84FA;
   const GLenum DEPTH24_STENCIL8                              = 0x88F0;
   const GLenum UNSIGNED_NORMALIZED                           = 0x8C17;
   const GLenum DRAW_FRAMEBUFFER_BINDING                      = 0x8CA6; /* Same as FRAMEBUFFER_BINDING */
   const GLenum READ_FRAMEBUFFER                              = 0x8CA8;
   const GLenum DRAW_FRAMEBUFFER                              = 0x8CA9;
@@ -298,19 +299,23 @@ interface WebGL2RenderingContextBase
 
   const GLint64 TIMEOUT_IGNORED                              = -1;
 
   /* WebGL-specific enums */
   const GLenum MAX_CLIENT_WAIT_TIMEOUT_WEBGL                 = 0x9247;
 
   /* Buffer objects */
   // WebGL1:
-  // void bufferData(GLenum target, GLsizeiptr size, GLenum usage);
-  // void bufferData(GLenum target, [AllowShared] BufferSource? srcData, GLenum usage);
-  // void bufferSubData(GLenum target, GLintptr dstByteOffset, [AllowShared] BufferSource srcData);
+  // BUG: https://github.com/KhronosGroup/WebGL/issues/2216
+  // FIXME(xanewok): https://github.com/servo/servo/issues/20513
+  [Throws]
+  void bufferData(GLenum target, object? data, GLenum usage);
+  [Throws]
+  void bufferData(GLenum target, GLsizeiptr size, GLenum usage);
+  void bufferSubData(GLenum target, GLintptr dstByteOffset, /*[AllowShared]*/ BufferSource srcData);
   // WebGL2:
   // void bufferData(GLenum target, [AllowShared] ArrayBufferView srcData, GLenum usage, GLuint srcOffset,
   //                 optional GLuint length = 0);
   // void bufferSubData(GLenum target, GLintptr dstByteOffset, [AllowShared] ArrayBufferView srcData,
   //                    GLuint srcOffset, optional GLuint length = 0);
 
   // void copyBufferSubData(GLenum readTarget, GLenum writeTarget, GLintptr readOffset,
   //                        GLintptr writeOffset, GLsizeiptr size);
@@ -337,27 +342,33 @@ interface WebGL2RenderingContextBase
 
   /* Texture objects */
   // void texStorage2D(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width,
   //                   GLsizei height);
   // void texStorage3D(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width,
   //                   GLsizei height, GLsizei depth);
 
   // WebGL1 legacy entrypoints:
-  // void texImage2D(GLenum target, GLint level, GLint internalformat,
-  //                 GLsizei width, GLsizei height, GLint border, GLenum format,
-  //                 GLenum type, [AllowShared] ArrayBufferView? pixels);
-  // void texImage2D(GLenum target, GLint level, GLint internalformat,
-  //                 GLenum format, GLenum type, TexImageSource source); // May throw DOMException
+  // BUG: https://github.com/KhronosGroup/WebGL/issues/2216
+  [Throws]
+  void texImage2D(GLenum target, GLint level, GLenum internalformat,
+                  GLsizei width, GLsizei height, GLint border, GLenum format,
+                  GLenum type, /*[AllowShared]*/ ArrayBufferView? pixels);
+  [Throws]
+  void texImage2D(GLenum target, GLint level, GLenum internalformat,
+                  GLenum format, GLenum type, TexImageSource source); // May throw DOMException
 
-  // void texSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset,
-  //                    GLsizei width, GLsizei height,
-  //                    GLenum format, GLenum type, [AllowShared] ArrayBufferView? pixels);
-  // void texSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset,
-  //                    GLenum format, GLenum type, TexImageSource source); // May throw DOMException
+  // BUG: https://github.com/KhronosGroup/WebGL/issues/2216
+  [Throws]
+  void texSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset,
+                     GLsizei width, GLsizei height,
+                     GLenum format, GLenum type, /*[AllowShared]*/ ArrayBufferView? pixels);
+  [Throws]
+  void texSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset,
+                     GLenum format, GLenum type, TexImageSource source); // May throw DOMException
 
   // WebGL2 entrypoints:
   // void texImage2D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height,
   //                 GLint border, GLenum format, GLenum type, GLintptr pboOffset);
   // void texImage2D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height,
   //                 GLint border, GLenum format, GLenum type,
   //                 TexImageSource source); // May throw DOMException
   // void texImage2D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height,
@@ -493,18 +504,19 @@ interface WebGL2RenderingContextBase
   /* Writing to the drawing buffer */
   // void vertexAttribDivisor(GLuint index, GLuint divisor);
   // void drawArraysInstanced(GLenum mode, GLint first, GLsizei count, GLsizei instanceCount);
   // void drawElementsInstanced(GLenum mode, GLsizei count, GLenum type, GLintptr offset, GLsizei instanceCount);
   // void drawRangeElements(GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, GLintptr offset);
 
   /* Reading back pixels */
   // WebGL1:
-  // void readPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type,
-  //                 [AllowShared] ArrayBufferView? dstData);
+  // BUG: https://github.com/KhronosGroup/WebGL/issues/2216
+  void readPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type,
+                  /*[AllowShared]*/ ArrayBufferView? dstData);
   // WebGL2:
   // void readPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type,
   //                 GLintptr offset);
   // void readPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type,
   //                 [AllowShared] ArrayBufferView dstData, GLuint dstOffset);
 
   /* Multiple Render Targets */
   // void drawBuffers(sequence<GLenum> buffers);
--- a/servo/components/script/dom/webidls/WebGLRenderingContext.webidl
+++ b/servo/components/script/dom/webidls/WebGLRenderingContext.webidl
@@ -486,22 +486,20 @@ interface WebGLRenderingContextBase
     void bindTexture(GLenum target, WebGLTexture? texture);
     void blendColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha);
     void blendEquation(GLenum mode);
     void blendEquationSeparate(GLenum modeRGB, GLenum modeAlpha);
     void blendFunc(GLenum sfactor, GLenum dfactor);
     void blendFuncSeparate(GLenum srcRGB, GLenum dstRGB,
                            GLenum srcAlpha, GLenum dstAlpha);
 
-    // FIXME(xanewok): https://github.com/servo/servo/issues/20513
-    [Throws]
-    void bufferData(GLenum target, object? data, GLenum usage);
-    [Throws]
-    void bufferData(GLenum target, GLsizeiptr size, GLenum usage);
-    void bufferSubData(GLenum target, GLintptr offset, /*[AllowShared]*/ BufferSource? data);
+    // BUG: https://github.com/KhronosGroup/WebGL/issues/2216
+    // void bufferData(GLenum target, object? data, GLenum usage);
+    // void bufferData(GLenum target, GLsizeiptr size, GLenum usage);
+    // void bufferSubData(GLenum target, GLintptr offset, /*[AllowShared]*/ BufferSource data);
 
     [WebGLHandlesContextLoss] GLenum checkFramebufferStatus(GLenum target);
     void clear(GLbitfield mask);
     void clearColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha);
     void clearDepth(GLclampf depth);
     void clearStencil(GLint s);
     void colorMask(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha);
     void compileShader(WebGLShader shader);
@@ -599,56 +597,53 @@ interface WebGLRenderingContextBase
     [WebGLHandlesContextLoss] GLboolean isRenderbuffer(WebGLRenderbuffer? renderbuffer);
     [WebGLHandlesContextLoss] GLboolean isShader(WebGLShader? shader);
     [WebGLHandlesContextLoss] GLboolean isTexture(WebGLTexture? texture);
     void lineWidth(GLfloat width);
     void linkProgram(WebGLProgram? program);
     void pixelStorei(GLenum pname, GLint param);
     void polygonOffset(GLfloat factor, GLfloat units);
 
-    void readPixels(GLint x, GLint y, GLsizei width, GLsizei height,
-                    GLenum format, GLenum type, /*[AllowShared]*/ ArrayBufferView? pixels);
+    // BUG: https://github.com/KhronosGroup/WebGL/issues/2216
+    // void readPixels(GLint x, GLint y, GLsizei width, GLsizei height,
+    //                 GLenum format, GLenum type, /*[AllowShared]*/ ArrayBufferView? pixels);
 
     void renderbufferStorage(GLenum target, GLenum internalformat,
                              GLsizei width, GLsizei height);
     void sampleCoverage(GLclampf value, GLboolean invert);
     void scissor(GLint x, GLint y, GLsizei width, GLsizei height);
 
     void shaderSource(WebGLShader shader, DOMString source);
 
     void stencilFunc(GLenum func, GLint ref, GLuint mask);
     void stencilFuncSeparate(GLenum face, GLenum func, GLint ref, GLuint mask);
     void stencilMask(GLuint mask);
     void stencilMaskSeparate(GLenum face, GLuint mask);
     void stencilOp(GLenum fail, GLenum zfail, GLenum zpass);
     void stencilOpSeparate(GLenum face, GLenum fail, GLenum zfail, GLenum zpass);
 
-    // FIXME: https://github.com/servo/servo/issues/20516
-    [Throws]
-    void texImage2D(GLenum target, GLint level, GLenum internalformat,
-                    GLsizei width, GLsizei height, GLint border, GLenum format,
-                    GLenum type, /*[AllowShared]*/ ArrayBufferView? pixels);
-    [Throws]
-    void texImage2D(GLenum target, GLint level, GLenum internalformat,
-                    GLenum format, GLenum type, TexImageSource source); // May throw DOMException
+    // BUG: https://github.com/KhronosGroup/WebGL/issues/2216
+    // void texImage2D(GLenum target, GLint level, GLenum internalformat,
+    //                 GLsizei width, GLsizei height, GLint border, GLenum format,
+    //                 GLenum type, /*[AllowShared]*/ ArrayBufferView? pixels);
+    // void texImage2D(GLenum target, GLint level, GLenum internalformat,
+    //                 GLenum format, GLenum type, TexImageSource source); // May throw DOMException
     [Throws, Pref="dom.webgl.dom_to_texture.enabled"]
     void texImageDOM(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height,
                      GLenum format, GLenum type, HTMLIFrameElement source); // May throw DOMException
 
     void texParameterf(GLenum target, GLenum pname, GLfloat param);
     void texParameteri(GLenum target, GLenum pname, GLint param);
 
-    // FIXME: https://github.com/servo/servo/issues/20516
-    [Throws]
-    void texSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset,
-                      GLsizei width, GLsizei height,
-                      GLenum format, GLenum type, /*[AllowShared]*/ ArrayBufferView? pixels);
-    [Throws]
-    void texSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset,
-                       GLenum format, GLenum type, TexImageSource source); // May throw DOMException
+    // BUG: https://github.com/KhronosGroup/WebGL/issues/2216
+    // void texSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset,
+    //                   GLsizei width, GLsizei height,
+    //                   GLenum format, GLenum type, /*[AllowShared]*/ ArrayBufferView? pixels);
+    // void texSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset,
+    //                    GLenum format, GLenum type, TexImageSource source); // May throw DOMException
 
     void uniform1f(WebGLUniformLocation? location, GLfloat x);
     void uniform2f(WebGLUniformLocation? location, GLfloat x, GLfloat y);
     void uniform3f(WebGLUniformLocation? location, GLfloat x, GLfloat y, GLfloat z);
     void uniform4f(WebGLUniformLocation? location, GLfloat x, GLfloat y, GLfloat z, GLfloat w);
 
     void uniform1i(WebGLUniformLocation? location, GLint x);
     void uniform2i(WebGLUniformLocation? location, GLint x, GLint y);
@@ -686,10 +681,39 @@ interface WebGLRenderingContextBase
                              GLboolean normalized, GLsizei stride, GLintptr offset);
 
     void viewport(GLint x, GLint y, GLsizei width, GLsizei height);
 };
 
 [Exposed=Window]
 interface WebGLRenderingContext
 {
+    // BUG: https://github.com/KhronosGroup/WebGL/issues/2216
+
+    // FIXME(xanewok): https://github.com/servo/servo/issues/20513
+    [Throws]
+    void bufferData(GLenum target, object? data, GLenum usage);
+    [Throws]
+    void bufferData(GLenum target, GLsizeiptr size, GLenum usage);
+    void bufferSubData(GLenum target, GLintptr offset, /*[AllowShared]*/ BufferSource data);
+
+    // FIXME: https://github.com/servo/servo/issues/20516
+    [Throws]
+    void texImage2D(GLenum target, GLint level, GLenum internalformat,
+                    GLsizei width, GLsizei height, GLint border, GLenum format,
+                    GLenum type, /*[AllowShared]*/ ArrayBufferView? pixels);
+    [Throws]
+    void texImage2D(GLenum target, GLint level, GLenum internalformat,
+                    GLenum format, GLenum type, TexImageSource source); // May throw DOMException
+
+    // FIXME: https://github.com/servo/servo/issues/20516
+    [Throws]
+    void texSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset,
+                      GLsizei width, GLsizei height,
+                      GLenum format, GLenum type, /*[AllowShared]*/ ArrayBufferView? pixels);
+    [Throws]
+    void texSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset,
+                       GLenum format, GLenum type, TexImageSource source); // May throw DOMException
+
+    void readPixels(GLint x, GLint y, GLsizei width, GLsizei height,
+                    GLenum format, GLenum type, /*[AllowShared]*/ ArrayBufferView? pixels);
 };
 WebGLRenderingContext implements WebGLRenderingContextBase;