Bug 1293845 - Repair texture bindings->internals glue. - r=mtseng
authorJeff Gilbert <jgilbert@mozilla.com>
Tue, 09 Aug 2016 17:16:09 -0700
changeset 340312 9ad41a92a8411248995bec256184eb88adc5a689
parent 340311 ad237809646117ebeac0574b9b61376be4129b1d
child 340313 ccdaa7a3d5156c7de1dfc9bee5d2244374f96d03
push id4
push userfmarier@mozilla.com
push dateSat, 20 Aug 2016 00:14:13 +0000
reviewersmtseng
bugs1293845
milestone51.0a1
Bug 1293845 - Repair texture bindings->internals glue. - r=mtseng MozReview-Commit-ID: CUDQGwhPTuU
dom/canvas/WebGL2Context.h
dom/canvas/WebGL2ContextBuffers.cpp
dom/canvas/WebGL2ContextTextures.cpp
dom/canvas/WebGLContext.h
dom/canvas/WebGLContextGL.cpp
dom/canvas/WebGLContextTextures.cpp
dom/canvas/WebGLTexture.h
dom/canvas/WebGLTextureUpload.cpp
--- a/dom/canvas/WebGL2Context.h
+++ b/dom/canvas/WebGL2Context.h
@@ -47,25 +47,22 @@ public:
                            GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size);
 
 private:
     template<typename BufferT>
     void GetBufferSubDataT(GLenum target, GLintptr offset, const BufferT& data);
 
 public:
     void GetBufferSubData(GLenum target, GLintptr offset,
-                          const dom::Nullable<dom::ArrayBuffer>& maybeData);
-    void GetBufferSubData(GLenum target, GLintptr offset,
-                          const dom::SharedArrayBuffer& data);
+                          const dom::ArrayBufferView& dstData);
     void ReadPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format,
                     GLenum type, WebGLsizeiptr offset, ErrorResult& out_error);
 
-    void ReadPixels(GLint x, GLint y, GLsizei width, GLsizei height,
-                    GLenum format, GLenum type,
-                    const dom::Nullable<dom::ArrayBufferView>& pixels,
+    void ReadPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format,
+                    GLenum type, const dom::ArrayBufferView& pixels,
                     ErrorResult& out_error)
     {
         WebGLContext::ReadPixels(x, y, width, height, format, type, pixels, out_error);
     }
 
     // -------------------------------------------------------------------------
     // Framebuffer objects - WebGL2ContextFramebuffers.cpp
 
@@ -97,49 +94,38 @@ public:
 
     // -------------------------------------------------------------------------
     // Texture objects - WebGL2ContextTextures.cpp
 
     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);
+
     void TexImage3D(GLenum target, GLint level, GLenum internalFormat, GLsizei width,
                     GLsizei height, GLsizei depth, GLint border, GLenum unpackFormat,
-                    GLenum unpackType,
-                    const dom::Nullable<dom::ArrayBufferView>& pixels);
+                    GLenum unpackType, const dom::Nullable<dom::ArrayBufferView>& data);
+
     void TexSubImage3D(GLenum target, GLint level, GLint xOffset, GLint yOffset,
                        GLint zOffset, GLsizei width, GLsizei height, GLsizei depth,
                        GLenum unpackFormat, GLenum unpackType,
-                       const dom::Nullable<dom::ArrayBufferView>& pixels,
-                       ErrorResult& out_rv);
-    void TexSubImage3D(GLenum target, GLint level, GLint xOffset, GLint yOffset,
-                       GLint zOffset, GLenum unpackFormat, GLenum unpackType,
-                       dom::ImageData* data, ErrorResult& out_rv);
-protected:
+                       const dom::ArrayBufferView& data, ErrorResult&);
     void TexSubImage3D(GLenum target, GLint level, GLint xOffset, GLint yOffset,
                        GLint zOffset, GLenum unpackFormat, GLenum unpackType,
-                       dom::Element* elem, ErrorResult* const out_rv);
-public:
-    template<class T>
-    inline void
-    TexSubImage3D(GLenum target, GLint level, GLint xOffset, GLint yOffset, GLint zOffset,
-                  GLenum unpackFormat, GLenum unpackType, T& any, ErrorResult& out_rv)
-    {
-        TexSubImage3D(target, level, xOffset, yOffset, zOffset, unpackFormat, unpackType,
-                      &any, &out_rv);
-    }
+                       const dom::ImageData& data, ErrorResult&);
+    void TexSubImage3D(GLenum target, GLint level, GLint xOffset, GLint yOffset,
+                       GLint zOffset, GLenum unpackFormat, GLenum unpackType,
+                       const dom::Element& elem, ErrorResult& out_error);
 
     void CopyTexSubImage3D(GLenum target, GLint level, GLint xOffset, GLint yOffset,
                            GLint zOffset, GLint x, GLint y, GLsizei width,
                            GLsizei height);
     void CompressedTexImage3D(GLenum target, GLint level, GLenum internalFormat,
                               GLsizei width, GLsizei height, GLsizei depth,
-                              GLint border,
-                              const dom::ArrayBufferView& data);
+                              GLint border, const dom::ArrayBufferView& data);
     void CompressedTexSubImage3D(GLenum target, GLint level, GLint xOffset, GLint yOffset,
                                  GLint zOffset, GLsizei width, GLsizei height,
                                  GLsizei depth, GLenum sizedUnpackFormat,
                                  const dom::ArrayBufferView& data);
 
     ////////////////
     // Texture PBOs
 
@@ -170,35 +156,36 @@ public:
     {
         WebGLContext::TexImage2D(texImageTarget, level, internalFormat, width, height,
                                  border, unpackFormat, unpackType, pixels, out_rv);
     }
 
     template<typename T>
     void
     TexImage2D(GLenum texImageTarget, GLint level, GLenum internalFormat,
-               GLenum unpackFormat, GLenum unpackType, T& any, ErrorResult& out_rv)
+               GLenum unpackFormat, GLenum unpackType, const T& any, ErrorResult& out_rv)
     {
         WebGLContext::TexImage2D(texImageTarget, level, internalFormat, unpackFormat,
                                  unpackType, any, out_rv);
     }
 
     void
     TexSubImage2D(GLenum texImageTarget, GLint level, GLint xOffset, GLint yOffset,
                   GLsizei width, GLsizei height, GLenum unpackFormat, GLenum unpackType,
-                  const dom::Nullable<dom::ArrayBufferView>& pixels, ErrorResult& out_rv)
+                  const dom::ArrayBufferView& view, ErrorResult&)
     {
         WebGLContext::TexSubImage2D(texImageTarget, level, xOffset, yOffset, width,
-                                    height, unpackFormat, unpackType, pixels, out_rv);
+                                    height, unpackFormat, unpackType, view);
     }
 
     template<typename T>
     inline void
     TexSubImage2D(GLenum texImageTarget, GLint level, GLint xOffset, GLint yOffset,
-                  GLenum unpackFormat, GLenum unpackType, T& any, ErrorResult& out_rv)
+                  GLenum unpackFormat, GLenum unpackType, const T& any,
+                  ErrorResult& out_rv)
     {
         WebGLContext::TexSubImage2D(texImageTarget, level, xOffset, yOffset, unpackFormat,
                                     unpackType, any, out_rv);
     }
 
     // -------------------------------------------------------------------------
     // Programs and shaders - WebGL2ContextPrograms.cpp
     GLint GetFragDataLocation(WebGLProgram* program, const nsAString& name);
--- a/dom/canvas/WebGL2ContextBuffers.cpp
+++ b/dom/canvas/WebGL2ContextBuffers.cpp
@@ -135,22 +135,19 @@ WebGL2Context::CopyBufferSubData(GLenum 
 
     if (writeType == WebGLBuffer::Kind::Undefined) {
         writeBuffer->BindTo(
             (readType == WebGLBuffer::Kind::OtherData) ? LOCAL_GL_ARRAY_BUFFER
                                                        : LOCAL_GL_ELEMENT_ARRAY_BUFFER);
     }
 }
 
-// BufferT may be one of
-// const dom::ArrayBuffer&
-// const dom::SharedArrayBuffer&
-template<typename BufferT>
 void
-WebGL2Context::GetBufferSubDataT(GLenum target, GLintptr offset, const BufferT& data)
+WebGL2Context::GetBufferSubData(GLenum target, GLintptr offset,
+                                const dom::ArrayBufferView& data)
 {
     const char funcName[] = "getBufferSubData";
     if (IsContextLost())
         return;
 
     // For the WebGLBuffer bound to the passed target, read
     // returnedData.byteLength bytes from the buffer starting at byte
     // offset offset and write them to returnedData.
@@ -230,31 +227,9 @@ WebGL2Context::GetBufferSubDataT(GLenum 
 
     ////
 
     if (target == LOCAL_GL_TRANSFORM_FEEDBACK_BUFFER && currentTF) {
         BindTransformFeedback(LOCAL_GL_TRANSFORM_FEEDBACK, currentTF);
     }
 }
 
-void
-WebGL2Context::GetBufferSubData(GLenum target, GLintptr offset,
-                                const dom::Nullable<dom::ArrayBuffer>& maybeData)
-{
-    // If returnedData is null then an INVALID_VALUE error is
-    // generated.
-    if (maybeData.IsNull()) {
-        ErrorInvalidValue("getBufferSubData: returnedData is null");
-        return;
-    }
-
-    const dom::ArrayBuffer& data = maybeData.Value();
-    GetBufferSubDataT(target, offset, data);
-}
-
-void
-WebGL2Context::GetBufferSubData(GLenum target, GLintptr offset,
-                                const dom::SharedArrayBuffer& data)
-{
-    GetBufferSubDataT(target, offset, data);
-}
-
 } // namespace mozilla
--- a/dom/canvas/WebGL2ContextTextures.cpp
+++ b/dom/canvas/WebGL2ContextTextures.cpp
@@ -53,31 +53,35 @@ WebGL2Context::TexImage3D(GLenum rawTexI
     TexImageTarget target;
     WebGLTexture* tex;
     if (!ValidateTexImageTarget(this, funcName, funcDims, rawTexImageTarget, &target,
                                 &tex))
     {
         return;
     }
 
+    const dom::ArrayBufferView* view = nullptr;
+    if (!maybeView.IsNull()) {
+        view = &maybeView.Value();
+    }
+
     const bool isSubImage = false;
     const GLint xOffset = 0;
     const GLint yOffset = 0;
     const GLint zOffset = 0;
     tex->TexOrSubImage(isSubImage, funcName, target, level, internalFormat, xOffset,
                        yOffset, zOffset, width, height, depth, border, unpackFormat,
-                       unpackType, maybeView);
+                       unpackType, view);
 }
 
 void
 WebGL2Context::TexSubImage3D(GLenum rawTexImageTarget, GLint level, GLint xOffset,
                              GLint yOffset, GLint zOffset, GLsizei width, GLsizei height,
                              GLsizei depth, GLenum unpackFormat, GLenum unpackType,
-                             const dom::Nullable<dom::ArrayBufferView>& maybeView,
-                             ErrorResult& /*out_rv*/)
+                             const dom::ArrayBufferView& view, ErrorResult&)
 {
     const char funcName[] = "texSubImage3D";
     const uint8_t funcDims = 3;
 
     TexImageTarget target;
     WebGLTexture* tex;
     if (!ValidateTexImageTarget(this, funcName, funcDims, rawTexImageTarget, &target,
                                 &tex))
@@ -85,24 +89,24 @@ WebGL2Context::TexSubImage3D(GLenum rawT
         return;
     }
 
     const bool isSubImage = true;
     const GLenum internalFormat = 0;
     const GLint border = 0;
     tex->TexOrSubImage(isSubImage, funcName, target, level, internalFormat, xOffset,
                        yOffset, zOffset, width, height, depth, border, unpackFormat,
-                       unpackType, maybeView);
+                       unpackType, &view);
 }
 
 void
 WebGL2Context::TexSubImage3D(GLenum rawTexImageTarget, GLint level, GLint xOffset,
                              GLint yOffset, GLint zOffset, GLenum unpackFormat,
-                             GLenum unpackType, dom::ImageData* imageData,
-                             ErrorResult& /*out_rv*/)
+                             GLenum unpackType, const dom::ImageData& imageData,
+                             ErrorResult&)
 {
     const char funcName[] = "texSubImage3D";
     const uint8_t funcDims = 3;
 
     TexImageTarget target;
     WebGLTexture* tex;
     if (!ValidateTexImageTarget(this, funcName, funcDims, rawTexImageTarget, &target,
                                 &tex))
@@ -114,34 +118,34 @@ WebGL2Context::TexSubImage3D(GLenum rawT
     const GLenum internalFormat = 0;
     tex->TexOrSubImage(isSubImage, funcName, target, level, internalFormat, xOffset,
                        yOffset, zOffset, unpackFormat, unpackType, imageData);
 }
 
 void
 WebGL2Context::TexSubImage3D(GLenum rawTexImageTarget, GLint level, GLint xOffset,
                              GLint yOffset, GLint zOffset, GLenum unpackFormat,
-                             GLenum unpackType, dom::Element* elem,
-                             ErrorResult* const out_rv)
+                             GLenum unpackType, const dom::Element& elem,
+                             ErrorResult& out_rv)
 {
     const char funcName[] = "texSubImage3D";
     const uint8_t funcDims = 3;
 
     TexImageTarget target;
     WebGLTexture* tex;
     if (!ValidateTexImageTarget(this, funcName, funcDims, rawTexImageTarget, &target,
                                 &tex))
     {
         return;
     }
 
     const bool isSubImage = true;
     const GLenum internalFormat = 0;
     tex->TexOrSubImage(isSubImage, funcName, target, level, internalFormat, xOffset,
-                       yOffset, zOffset, unpackFormat, unpackType, elem, out_rv);
+                       yOffset, zOffset, unpackFormat, unpackType, elem, &out_rv);
 }
 
 void
 WebGL2Context::CompressedTexImage3D(GLenum rawTexImageTarget, GLint level,
                                     GLenum internalFormat, GLsizei width, GLsizei height,
                                     GLsizei depth, GLint border,
                                     const dom::ArrayBufferView& view)
 {
--- a/dom/canvas/WebGLContext.h
+++ b/dom/canvas/WebGLContext.h
@@ -547,20 +547,30 @@ protected:
     bool ReadPixels_SharedPrecheck(ErrorResult* const out_error);
     void ReadPixelsImpl(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format,
                         GLenum type, void* data, uint32_t dataLen);
     bool DoReadPixelsAndConvert(const webgl::FormatInfo* srcFormat, GLint x, GLint y,
                                 GLsizei width, GLsizei height, GLenum format,
                                 GLenum destType, void* dest, uint32_t dataLen,
                                 uint32_t rowStride);
 public:
-    void ReadPixels(GLint x, GLint y, GLsizei width, GLsizei height,
-                    GLenum format, GLenum type,
-                    const dom::Nullable<dom::ArrayBufferView>& pixels,
-                    ErrorResult& rv);
+    void ReadPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format,
+                    GLenum type, const dom::Nullable<dom::ArrayBufferView>& maybeView,
+                    ErrorResult& rv)
+    {
+        const char funcName[] = "readPixels";
+        if (maybeView.IsNull()) {
+            ErrorInvalidValue("%s: `pixels` must not be null.", funcName);
+            return;
+        }
+        ReadPixels(x, y, width, height, format, type, maybeView.Value(), rv);
+    }
+
+    void ReadPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format,
+                    GLenum type, const dom::ArrayBufferView& pixels, ErrorResult& rv);
     void RenderbufferStorage(GLenum target, GLenum internalFormat,
                              GLsizei width, GLsizei height);
 protected:
     void RenderbufferStorage_base(const char* funcName, GLenum target,
                                   GLsizei samples, GLenum internalformat,
                                   GLsizei width, GLsizei height);
 public:
     void SampleCoverage(GLclampf value, WebGLboolean invert);
@@ -847,58 +857,87 @@ public:
                                  GLenum unpackFormat, const dom::ArrayBufferView& view);
 
     void CopyTexImage2D(GLenum texImageTarget, GLint level, GLenum internalFormat,
                         GLint x, GLint y, GLsizei width, GLsizei height, GLint border);
     void CopyTexSubImage2D(GLenum texImageTarget, GLint level, GLint xOffset,
                            GLint yOffset, GLint x, GLint y, GLsizei width,
                            GLsizei height);
 
+    ////
+
     void TexImage2D(GLenum texImageTarget, GLint level, GLenum internalFormat,
                     GLsizei width, GLsizei height, GLint border, GLenum unpackFormat,
                     GLenum unpackType,
                     const dom::Nullable<dom::ArrayBufferView>& maybeView,
                     ErrorResult&);
+protected:
     void TexImage2D(GLenum texImageTarget, GLint level, GLenum internalFormat,
-                    GLenum unpackFormat, GLenum unpackType, dom::ImageData* imageData,
-                    ErrorResult&);
+                    GLenum unpackFormat, GLenum unpackType,
+                    const dom::ImageData& imageData, ErrorResult& out_error);
+public:
     void TexImage2D(GLenum texImageTarget, GLint level, GLenum internalFormat,
-                    GLenum unpackFormat, GLenum unpackType, dom::Element* elem,
-                    ErrorResult* const out_error);
+                    GLenum unpackFormat, GLenum unpackType, const dom::Element& elem,
+                    ErrorResult& out_error);
+
+    ////
+
+protected:
+    void TexSubImage2D(GLenum texImageTarget, GLint level, GLint xOffset, GLint yOffset,
+                       GLsizei width, GLsizei height, GLenum unpackFormat,
+                       GLenum unpackType, const dom::ArrayBufferView& view);
+    void TexSubImage2D(GLenum texImageTarget, GLint level, GLint xOffset, GLint yOffset,
+                       GLenum unpackFormat, GLenum unpackType,
+                       const dom::ImageData& imageData, ErrorResult& out_error);
+public:
+    void TexSubImage2D(GLenum texImageTarget, GLint level, GLint xOffset, GLint yOffset,
+                       GLenum unpackFormat, GLenum unpackType, const dom::Element& elem,
+                       ErrorResult& out_error);
+
+    ////////////////
+    // Pseudo-nullable WebGL1 entrypoints
+
+    void TexImage2D(GLenum texImageTarget, GLint level, GLenum internalFormat,
+                    GLenum unpackFormat, GLenum unpackType,
+                    const dom::ImageData* imageData, ErrorResult& out_error)
+    {
+        const char funcName[] = "texImage2D";
+        if (!imageData) {
+            ErrorInvalidValue("%s: `data` must not be null.", funcName);
+            return;
+        }
+        TexImage2D(texImageTarget, level, internalFormat, unpackFormat, unpackType,
+                   *imageData, out_error);
+    }
 
     void TexSubImage2D(GLenum texImageTarget, GLint level, GLint xOffset, GLint yOffset,
                        GLsizei width, GLsizei height, GLenum unpackFormat,
                        GLenum unpackType,
-                       const dom::Nullable<dom::ArrayBufferView>& maybeView,
-                       ErrorResult&);
-    void TexSubImage2D(GLenum texImageTarget, GLint level, GLint xOffset, GLint yOffset,
-                       GLenum unpackFormat, GLenum unpackType, dom::ImageData* imageData,
-                       ErrorResult&);
-    void TexSubImage2D(GLenum texImageTarget, GLint level, GLint xOffset, GLint yOffset,
-                       GLenum unpackFormat, GLenum unpackType, dom::Element* elem,
-                       ErrorResult* const out_error);
-
-    // Allow whatever element unpackTypes the bindings are willing to pass
-    // us in Tex(Sub)Image2D
-    template<typename T>
-    inline void
-    TexImage2D(GLenum texImageTarget, GLint level, GLenum internalFormat,
-               GLenum unpackFormat, GLenum unpackType, T& elem, ErrorResult& out_error)
+                       const dom::Nullable<dom::ArrayBufferView>& maybeView, ErrorResult&)
     {
-        TexImage2D(texImageTarget, level, internalFormat, unpackFormat, unpackType, &elem,
-                   &out_error);
+        const char funcName[] = "texSubImage2D";
+        if (maybeView.IsNull()) {
+            ErrorInvalidValue("%s: `data` must not be null.", funcName);
+            return;
+        }
+        TexSubImage2D(texImageTarget, level, xOffset, yOffset, width, height,
+                      unpackFormat, unpackType, maybeView.Value());
     }
 
-    template<typename T>
-    inline void
-    TexSubImage2D(GLenum texImageTarget, GLint level, GLint xOffset, GLint yOffset,
-                  GLenum unpackFormat, GLenum unpackType, T& elem, ErrorResult& out_error)
+    void TexSubImage2D(GLenum texImageTarget, GLint level, GLint xOffset, GLint yOffset,
+                       GLenum unpackFormat, GLenum unpackType,
+                       const dom::ImageData* imageData, ErrorResult& out_error)
     {
+        const char funcName[] = "texSubImage2D";
+        if (!imageData) {
+            ErrorInvalidValue("%s: `data` must not be null.", funcName);
+            return;
+        }
         TexSubImage2D(texImageTarget, level, xOffset, yOffset, unpackFormat, unpackType,
-                      &elem, &out_error);
+                      *imageData, out_error);
     }
 
     //////
     // WebGLTextureUpload.cpp
 public:
     bool ValidateUnpackPixels(const char* funcName, uint32_t fullRows,
                               uint32_t tailPixels, webgl::TexUnpackBlob* blob);
 
--- a/dom/canvas/WebGLContextGL.cpp
+++ b/dom/canvas/WebGLContextGL.cpp
@@ -1498,39 +1498,29 @@ WebGLContext::ValidatePackSize(const cha
 
     *out_rowStride = rowStride.value();
     *out_endOffset = usedBytesPerImage.value();
     return true;
 }
 
 void
 WebGLContext::ReadPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format,
-                         GLenum type,
-                         const dom::Nullable<dom::ArrayBufferView>& pixels,
+                         GLenum type, const dom::ArrayBufferView& view,
                          ErrorResult& out_error)
 {
     if (!ReadPixels_SharedPrecheck(&out_error))
         return;
 
     if (mBoundPixelPackBuffer) {
         ErrorInvalidOperation("readPixels: PIXEL_PACK_BUFFER must be null.");
         return;
     }
 
     //////
 
-    if (pixels.IsNull()) {
-        ErrorInvalidValue("readPixels: null destination buffer");
-        return;
-    }
-
-    const auto& view = pixels.Value();
-
-    //////
-
     js::Scalar::Type reqScalarType;
     if (!GetJSScalarFromGLType(type, &reqScalarType)) {
         ErrorInvalidEnum("readPixels: Bad `type`.");
         return;
     }
 
     const js::Scalar::Type dataScalarType = JS_GetArrayBufferViewType(view.Obj());
     if (dataScalarType != reqScalarType) {
--- a/dom/canvas/WebGLContextTextures.cpp
+++ b/dom/canvas/WebGLContextTextures.cpp
@@ -337,30 +337,35 @@ WebGLContext::TexImage2D(GLenum rawTexIm
     TexImageTarget target;
     WebGLTexture* tex;
     if (!ValidateTexImageTarget(this, funcName, funcDims, rawTexImageTarget, &target,
                                 &tex))
     {
         return;
     }
 
+    const dom::ArrayBufferView* view = nullptr;
+    if (!maybeView.IsNull()) {
+        view = &maybeView.Value();
+    }
+
     const bool isSubImage = false;
     const GLint xOffset = 0;
     const GLint yOffset = 0;
     const GLint zOffset = 0;
     const GLsizei depth = 1;
     tex->TexOrSubImage(isSubImage, funcName, target, level, internalFormat, xOffset,
                        yOffset, zOffset, width, height, depth, border, unpackFormat,
-                       unpackType, maybeView);
+                       unpackType, view);
 }
 
 void
 WebGLContext::TexImage2D(GLenum rawTexImageTarget, GLint level, GLenum internalFormat,
                          GLenum unpackFormat, GLenum unpackType,
-                         dom::ImageData* imageData, ErrorResult&)
+                         const dom::ImageData& imageData, ErrorResult&)
 {
     const char funcName[] = "texImage2D";
     const uint8_t funcDims = 2;
 
     TexImageTarget target;
     WebGLTexture* tex;
     if (!ValidateTexImageTarget(this, funcName, funcDims, rawTexImageTarget, &target,
                                 &tex))
@@ -373,18 +378,18 @@ WebGLContext::TexImage2D(GLenum rawTexIm
     const GLint yOffset = 0;
     const GLint zOffset = 0;
     tex->TexOrSubImage(isSubImage, funcName, target, level, internalFormat, xOffset,
                        yOffset, zOffset, unpackFormat, unpackType, imageData);
 }
 
 void
 WebGLContext::TexImage2D(GLenum rawTexImageTarget, GLint level, GLenum internalFormat,
-                         GLenum unpackFormat, GLenum unpackType, dom::Element* elem,
-                         ErrorResult* const out_error)
+                         GLenum unpackFormat, GLenum unpackType, const dom::Element& elem,
+                         ErrorResult& out_error)
 {
     const char funcName[] = "texImage2D";
     const uint8_t funcDims = 2;
 
     TexImageTarget target;
     WebGLTexture* tex;
     if (!ValidateTexImageTarget(this, funcName, funcDims, rawTexImageTarget, &target,
                                 &tex))
@@ -392,28 +397,27 @@ WebGLContext::TexImage2D(GLenum rawTexIm
         return;
     }
 
     const bool isSubImage = false;
     const GLint xOffset = 0;
     const GLint yOffset = 0;
     const GLint zOffset = 0;
     tex->TexOrSubImage(isSubImage, funcName, target, level, internalFormat, xOffset,
-                       yOffset, zOffset, unpackFormat, unpackType, elem, out_error);
+                       yOffset, zOffset, unpackFormat, unpackType, elem, &out_error);
 }
 
 ////////////////////////////////////////
 // TexSubImage
 
 void
 WebGLContext::TexSubImage2D(GLenum rawTexImageTarget, GLint level, GLint xOffset,
                             GLint yOffset, GLsizei width, GLsizei height,
                             GLenum unpackFormat, GLenum unpackType,
-                            const dom::Nullable<dom::ArrayBufferView>& maybeView,
-                            ErrorResult&)
+                            const dom::ArrayBufferView& view)
 {
     const char funcName[] = "texSubImage2D";
     const uint8_t funcDims = 2;
 
     TexImageTarget target;
     WebGLTexture* tex;
     if (!ValidateTexImageTarget(this, funcName, funcDims, rawTexImageTarget, &target,
                                 &tex))
@@ -423,23 +427,23 @@ WebGLContext::TexSubImage2D(GLenum rawTe
 
     const bool isSubImage = true;
     const GLenum internalFormat = 0;
     const GLint zOffset = 0;
     const GLsizei depth = 1;
     const GLint border = 0;
     tex->TexOrSubImage(isSubImage, funcName, target, level, internalFormat, xOffset,
                        yOffset, zOffset, width, height, depth, border, unpackFormat,
-                       unpackType, maybeView);
+                       unpackType, &view);
 }
 
 void
 WebGLContext::TexSubImage2D(GLenum rawTexImageTarget, GLint level, GLint xOffset,
                             GLint yOffset, GLenum unpackFormat, GLenum unpackType,
-                            dom::ImageData* imageData, ErrorResult&)
+                            const dom::ImageData& imageData, ErrorResult&)
 {
     const char funcName[] = "texSubImage2D";
     const uint8_t funcDims = 2;
 
     TexImageTarget target;
     WebGLTexture* tex;
     if (!ValidateTexImageTarget(this, funcName, funcDims, rawTexImageTarget, &target,
                                 &tex))
@@ -452,34 +456,34 @@ WebGLContext::TexSubImage2D(GLenum rawTe
     const GLint zOffset = 0;
     tex->TexOrSubImage(isSubImage, funcName, target, level, internalFormat, xOffset,
                        yOffset, zOffset, unpackFormat, unpackType, imageData);
 }
 
 void
 WebGLContext::TexSubImage2D(GLenum rawTexImageTarget, GLint level, GLint xOffset,
                             GLint yOffset, GLenum unpackFormat, GLenum unpackType,
-                            dom::Element* elem, ErrorResult* const out_error)
+                            const dom::Element& elem, ErrorResult& out_error)
 {
     const char funcName[] = "texSubImage2D";
     const uint8_t funcDims = 2;
 
     TexImageTarget target;
     WebGLTexture* tex;
     if (!ValidateTexImageTarget(this, funcName, funcDims, rawTexImageTarget, &target,
                                 &tex))
     {
         return;
     }
 
     const bool isSubImage = true;
     const GLenum internalFormat = 0;
     const GLint zOffset = 0;
     tex->TexOrSubImage(isSubImage, funcName, target, level, internalFormat, xOffset,
-                       yOffset, zOffset, unpackFormat, unpackType, elem, out_error);
+                       yOffset, zOffset, unpackFormat, unpackType, elem, &out_error);
 }
 
 ////////////////////////////////////////
 // CompressedTex(Sub)Image
 
 void
 WebGLContext::CompressedTexImage2D(GLenum rawTexImageTarget, GLint level,
                                    GLenum internalFormat, GLsizei width, GLsizei height,
--- a/dom/canvas/WebGLTexture.h
+++ b/dom/canvas/WebGLTexture.h
@@ -231,27 +231,27 @@ public:
 
     ////////////////////////////////////
     // WebGLTextureUpload.cpp
 
     void TexOrSubImage(bool isSubImage, const char* funcName, TexImageTarget target,
                        GLint level, GLenum internalFormat, GLint xOffset, GLint yOffset,
                        GLint zOffset, GLsizei width, GLsizei height, GLsizei depth,
                        GLint border, GLenum unpackFormat, GLenum unpackType,
-                       const dom::Nullable<dom::ArrayBufferView>& maybeView);
+                       const dom::ArrayBufferView* view);
 
     void TexOrSubImage(bool isSubImage, const char* funcName, TexImageTarget target,
                        GLint level, GLenum internalFormat, GLint xOffset, GLint yOffset,
                        GLint zOffset, GLenum unpackFormat, GLenum unpackType,
-                       dom::ImageData* imageData);
+                       const dom::ImageData& imageData);
 
     void TexOrSubImage(bool isSubImage, const char* funcName, TexImageTarget target,
                        GLint level, GLenum internalFormat, GLint xOffset, GLint yOffset,
                        GLint zOffset, GLenum unpackFormat, GLenum unpackType,
-                       dom::Element* elem, ErrorResult* const out_error);
+                       const dom::Element& elem, ErrorResult* const out_error);
 
     void TexOrSubImage(bool isSubImage, const char* funcName, TexImageTarget target,
                        GLint level, GLenum internalFormat, GLint xOffset, GLint yOffset,
                        GLint zOffset, GLsizei width, GLsizei height, GLsizei depth,
                        GLint border, GLenum unpackFormat, GLenum unpackType,
                        WebGLsizeiptr offset);
 
 protected:
--- a/dom/canvas/WebGLTextureUpload.cpp
+++ b/dom/canvas/WebGLTextureUpload.cpp
@@ -222,17 +222,17 @@ WebGLContext::ValidateUnpackInfo(const c
 }
 
 void
 WebGLTexture::TexOrSubImage(bool isSubImage, const char* funcName, TexImageTarget target,
                             GLint level, GLenum internalFormat, GLint xOffset,
                             GLint yOffset, GLint zOffset, GLsizei rawWidth,
                             GLsizei rawHeight, GLsizei rawDepth, GLint border,
                             GLenum unpackFormat, GLenum unpackType,
-                            const dom::Nullable<dom::ArrayBufferView>& maybeView)
+                            const dom::ArrayBufferView* view)
 {
     uint32_t width, height, depth;
     if (!ValidateExtents(mContext, funcName, rawWidth, rawHeight, rawDepth, border,
                          &width, &height, &depth))
     {
         return;
     }
 
@@ -241,32 +241,27 @@ WebGLTexture::TexOrSubImage(bool isSubIm
     if (!mContext->ValidateUnpackInfo(funcName, usePBOs, unpackFormat, unpackType, &pi))
         return;
 
     ////
 
     const uint8_t* bytes = nullptr;
     uint32_t byteCount = 0;
 
-    if (!maybeView.IsNull()) {
-        const auto& view = maybeView.Value();
+    if (view) {
+        view->ComputeLengthAndData();
+        bytes = view->DataAllowShared();
+        byteCount = view->LengthAllowShared();
 
-        const auto jsType = JS_GetArrayBufferViewType(view.Obj());
+        const auto& jsType = view->Type();
         if (!DoesJSTypeMatchUnpackType(pi.type, jsType)) {
             mContext->ErrorInvalidOperation("%s: `pixels` not compatible with `type`.",
                                             funcName);
             return;
         }
-
-        if (width && height && depth) {
-            view.ComputeLengthAndData();
-
-            bytes = view.DataAllowShared();
-            byteCount = view.LengthAllowShared();
-        }
     } else if (isSubImage) {
         mContext->ErrorInvalidValue("%s: `pixels` must not be null.", funcName);
         return;
     }
 
     const bool isClientData = true;
     webgl::TexUnpackBytes blob(mContext, target, width, height, depth, isClientData,
                                bytes);
@@ -331,26 +326,26 @@ WebGLTexture::TexOrSubImage(bool isSubIm
                       yOffset, zOffset, pi, &blob);
 }
 
 ////////////////////////////////////////
 // ImageData
 
 static already_AddRefed<gfx::DataSourceSurface>
 FromImageData(WebGLContext* webgl, const char* funcName, GLenum unpackType,
-              dom::ImageData* imageData, dom::Uint8ClampedArray* scopedArr)
+              const dom::ImageData& imageData, dom::Uint8ClampedArray* scopedArr)
 {
-    DebugOnly<bool> inited = scopedArr->Init(imageData->GetDataObject());
+    DebugOnly<bool> inited = scopedArr->Init(imageData.GetDataObject());
     MOZ_ASSERT(inited);
 
     scopedArr->ComputeLengthAndData();
     const DebugOnly<size_t> dataSize = scopedArr->Length();
     const void* const data = scopedArr->Data();
 
-    const gfx::IntSize size(imageData->Width(), imageData->Height());
+    const gfx::IntSize size(imageData.Width(), imageData.Height());
     const size_t stride = size.width * 4;
     const gfx::SurfaceFormat surfFormat = gfx::SurfaceFormat::R8G8B8A8;
 
     MOZ_ASSERT(dataSize == stride * size.height);
 
     uint8_t* wrappableData = (uint8_t*)data;
 
     RefPtr<gfx::DataSourceSurface> surf =
@@ -365,32 +360,26 @@ FromImageData(WebGLContext* webgl, const
 
     return surf.forget();
 }
 
 void
 WebGLTexture::TexOrSubImage(bool isSubImage, const char* funcName, TexImageTarget target,
                             GLint level, GLenum internalFormat, GLint xOffset,
                             GLint yOffset, GLint zOffset, GLenum unpackFormat,
-                            GLenum unpackType, dom::ImageData* imageData)
+                            GLenum unpackType, const dom::ImageData& imageData)
 {
     const bool usePBOs = false;
     webgl::PackingInfo pi;
     if (!mContext->ValidateUnpackInfo(funcName, usePBOs, unpackFormat, unpackType, &pi))
         return;
 
-    if (!imageData) {
-        // Spec says to generate an INVALID_VALUE error
-        mContext->ErrorInvalidValue("%s: Null ImageData.", funcName);
-        return;
-    }
-
     // Eventually, these will be args.
-    const uint32_t width = imageData->Width();
-    const uint32_t height = imageData->Height();
+    const uint32_t width = imageData.Width();
+    const uint32_t height = imageData.Height();
     const uint32_t depth = 1;
 
     dom::RootedTypedArray<dom::Uint8ClampedArray> scopedArr(dom::RootingCx());
     const RefPtr<gfx::DataSourceSurface> surf = FromImageData(mContext, funcName,
                                                               unpackType, imageData,
                                                               &scopedArr);
     if (!surf)
         return;
@@ -398,33 +387,33 @@ WebGLTexture::TexOrSubImage(bool isSubIm
     // WhatWG "HTML Living Standard" (30 October 2015):
     // "The getImageData(sx, sy, sw, sh) method [...] Pixels must be returned as
     //  non-premultiplied alpha values."
     const bool isAlphaPremult = false;
 
     webgl::TexUnpackSurface blob(mContext, target, width, height, depth, surf,
                                  isAlphaPremult);
 
-    const uint32_t fullRows = imageData->Height();
+    const uint32_t fullRows = imageData.Height();
     const uint32_t tailPixels = 0;
     if (!mContext->ValidateUnpackPixels(funcName, fullRows, tailPixels, &blob))
         return;
 
     TexOrSubImageBlob(isSubImage, funcName, target, level, internalFormat, xOffset,
                       yOffset, zOffset, pi, &blob);
 }
 
 ////////////////////////////////////////
 // dom::Element
 
 void
 WebGLTexture::TexOrSubImage(bool isSubImage, const char* funcName, TexImageTarget target,
                             GLint level, GLenum internalFormat, GLint xOffset,
                             GLint yOffset, GLint zOffset, GLenum unpackFormat,
-                            GLenum unpackType, dom::Element* elem,
+                            GLenum unpackType, const dom::Element& elem,
                             ErrorResult* const out_error)
 {
     const bool usePBOs = false;
     webgl::PackingInfo pi;
     if (!mContext->ValidateUnpackInfo(funcName, usePBOs, unpackFormat, unpackType, &pi))
         return;
 
     //////
@@ -434,17 +423,18 @@ WebGLTexture::TexOrSubImage(bool isSubIm
 
     if (mContext->mPixelStore_ColorspaceConversion == LOCAL_GL_NONE)
         flags |= nsLayoutUtils::SFE_NO_COLORSPACE_CONVERSION;
 
     if (!mContext->mPixelStore_PremultiplyAlpha)
         flags |= nsLayoutUtils::SFE_PREFER_NO_PREMULTIPLY_ALPHA;
 
     RefPtr<gfx::DrawTarget> idealDrawTarget = nullptr; // Don't care for now.
-    auto sfer = nsLayoutUtils::SurfaceFromElement(elem, flags, idealDrawTarget);
+    auto sfer = nsLayoutUtils::SurfaceFromElement(const_cast<dom::Element*>(&elem), flags,
+                                                  idealDrawTarget);
 
     //////
 
     uint32_t elemWidth = 0;
     uint32_t elemHeight = 0;
     layers::Image* layersImage = nullptr;
     if (!gfxPrefs::WebGLDisableDOMBlitUploads() && sfer.mLayersImage) {
         layersImage = sfer.mLayersImage;