Bug 1359055 - Part 1: PBO offset for WebGL compressedTexImage; r=baku,jgilbert
☠☠ backed out by 76edd38bb942 ☠ ☠
authordmu@mozilla.com <dmu@mozilla.com>
Tue, 18 Jul 2017 18:02:57 +0000
changeset 429655 7c2db4c459cc86c15aa1305cfb881f904ca31c4a
parent 429616 ae9e6b6d31321f119f1e07823f93137f58771377
child 429656 41850a57de472f05cb0177466c8d1c382052bdcd
push id1567
push userjlorenzo@mozilla.com
push dateThu, 02 Nov 2017 12:36:05 +0000
treeherdermozilla-release@e512c14a0406 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbaku, jgilbert
bugs1359055
milestone57.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
Bug 1359055 - Part 1: PBO offset for WebGL compressedTexImage; r=baku,jgilbert MozReview-Commit-ID: LN2diy41A2Z
dom/canvas/WebGL2Context.h
dom/canvas/WebGLContext.h
dom/canvas/WebGLContextTextures.cpp
dom/canvas/WebGLTexture.h
dom/canvas/WebGLTextureUpload.cpp
dom/webidl/WebGL2RenderingContext.webidl
--- a/dom/canvas/WebGL2Context.h
+++ b/dom/canvas/WebGL2Context.h
@@ -110,41 +110,64 @@ public:
 
 protected:
     void TexStorage(const char* funcName, uint8_t funcDims, GLenum target, GLsizei levels,
                     GLenum internalFormat, GLsizei width, GLsizei height, GLsizei depth);
 
     ////////////////////////////////////
 
 public:
+    void CompressedTexImage3D(GLenum target, GLint level, GLenum internalFormat,
+                              GLsizei width, GLsizei height, GLsizei depth, GLint border,
+                              GLsizei imageSize, WebGLintptr offset)
+    {
+        const char funcName[] = "compressedTexImage3D";
+        const uint8_t funcDims = 3;
+        const TexImageSourceAdapter src(&offset, 0, 0);
+        CompressedTexImage(funcName, funcDims, target, level, internalFormat, width,
+                           height, depth, border, src, Some(imageSize));
+    }
+
     template<typename T>
     void CompressedTexImage3D(GLenum target, GLint level, GLenum internalFormat,
                               GLsizei width, GLsizei height, GLsizei depth, GLint border,
                               const T& anySrc, GLuint viewElemOffset = 0,
                               GLuint viewElemLengthOverride = 0)
     {
         const char funcName[] = "compressedTexImage3D";
         const uint8_t funcDims = 3;
         const TexImageSourceAdapter src(&anySrc, viewElemOffset, viewElemLengthOverride);
         CompressedTexImage(funcName, funcDims, target, level, internalFormat, width,
-                           height, depth, border, src);
+                           height, depth, border, src, Nothing());
+    }
+
+    void CompressedTexSubImage3D(GLenum target, GLint level, GLint xOffset, GLint yOffset,
+                                 GLint zOffset, GLsizei width, GLsizei height,
+                                 GLsizei depth, GLenum unpackFormat,
+                                 GLsizei imageSize, WebGLintptr offset)
+    {
+        const char funcName[] = "compressedTexSubImage3D";
+        const uint8_t funcDims = 3;
+        const TexImageSourceAdapter src(&offset, 0, 0);
+        CompressedTexSubImage(funcName, funcDims, target, level, xOffset, yOffset,
+                              zOffset, width, height, depth, unpackFormat, src, Some(imageSize));
     }
 
     template<typename T>
     void CompressedTexSubImage3D(GLenum target, GLint level, GLint xOffset, GLint yOffset,
                                  GLint zOffset, GLsizei width, GLsizei height,
                                  GLsizei depth, GLenum unpackFormat, const T& anySrc,
                                  GLuint viewElemOffset = 0,
                                  GLuint viewElemLengthOverride = 0)
     {
         const char funcName[] = "compressedTexSubImage3D";
         const uint8_t funcDims = 3;
         const TexImageSourceAdapter src(&anySrc, viewElemOffset, viewElemLengthOverride);
         CompressedTexSubImage(funcName, funcDims, target, level, xOffset, yOffset,
-                              zOffset, width, height, depth, unpackFormat, src);
+                              zOffset, width, height, depth, unpackFormat, src, Nothing());
     }
 
     ////////////////////////////////////
 
     void CopyTexSubImage3D(GLenum target, GLint level, GLint xOffset, GLint yOffset,
                            GLint zOffset, GLint x, GLint y, GLsizei width,
                            GLsizei height)
     {
--- a/dom/canvas/WebGLContext.h
+++ b/dom/canvas/WebGLContext.h
@@ -1047,56 +1047,80 @@ protected:
     JS::Value GetTexParameter(GLenum texTarget, GLenum pname);
     void TexParameter_base(GLenum texTarget, GLenum pname, const FloatOrInt& param);
 
     virtual bool IsTexParamValid(GLenum pname) const;
 
     ////////////////////////////////////
 
 public:
+    void CompressedTexImage2D(GLenum target, GLint level, GLenum internalFormat,
+                              GLsizei width, GLsizei height, GLint border,
+                              GLsizei imageSize, WebGLsizeiptr offset)
+    {
+        const char funcName[] = "compressedTexImage2D";
+        const uint8_t funcDims = 2;
+        const GLsizei depth = 1;
+        const TexImageSourceAdapter src(&offset, 0, 0);
+        CompressedTexImage(funcName, funcDims, target, level, internalFormat, width,
+                           height, depth, border, src, Some(imageSize));
+    }
+
     template<typename T>
     void CompressedTexImage2D(GLenum target, GLint level, GLenum internalFormat,
                               GLsizei width, GLsizei height, GLint border,
                               const T& anySrc, GLuint viewElemOffset = 0,
                               GLuint viewElemLengthOverride = 0)
     {
         const char funcName[] = "compressedTexImage2D";
         const uint8_t funcDims = 2;
         const GLsizei depth = 1;
         const TexImageSourceAdapter src(&anySrc, viewElemOffset, viewElemLengthOverride);
         CompressedTexImage(funcName, funcDims, target, level, internalFormat, width,
-                           height, depth, border, src);
+                           height, depth, border, src, Nothing());
+    }
+
+    void CompressedTexSubImage2D(GLenum target, GLint level, GLint xOffset, GLint yOffset,
+                                 GLsizei width, GLsizei height, GLenum unpackFormat,
+                                 GLsizei imageSize, WebGLsizeiptr offset)
+    {
+        const char funcName[] = "compressedTexSubImage2D";
+        const uint8_t funcDims = 2;
+        const GLint zOffset = 0;
+        const GLsizei depth = 1;
+        const TexImageSourceAdapter src(&offset, 0, 0);
+        CompressedTexSubImage(funcName, funcDims, target, level, xOffset, yOffset,
+                              zOffset, width, height, depth, unpackFormat, src, Some(imageSize));
     }
 
     template<typename T>
     void CompressedTexSubImage2D(GLenum target, GLint level, GLint xOffset, GLint yOffset,
                                  GLsizei width, GLsizei height, GLenum unpackFormat,
                                  const T& anySrc, GLuint viewElemOffset = 0,
                                  GLuint viewElemLengthOverride = 0)
     {
         const char funcName[] = "compressedTexSubImage2D";
         const uint8_t funcDims = 2;
         const GLint zOffset = 0;
         const GLsizei depth = 1;
         const TexImageSourceAdapter src(&anySrc, viewElemOffset, viewElemLengthOverride);
         CompressedTexSubImage(funcName, funcDims, target, level, xOffset, yOffset,
-                              zOffset, width, height, depth, unpackFormat, src);
+                              zOffset, width, height, depth, unpackFormat, src, Nothing());
     }
 
 protected:
     void CompressedTexImage(const char* funcName, uint8_t funcDims, GLenum target,
                             GLint level, GLenum internalFormat, GLsizei width,
                             GLsizei height, GLsizei depth, GLint border,
-                            const TexImageSource& src);
-
+                            const TexImageSource& src, const Maybe<GLsizei>& expectedImageSize);
     void CompressedTexSubImage(const char* funcName, uint8_t funcDims, GLenum target,
                                GLint level, GLint xOffset, GLint yOffset, GLint zOffset,
                                GLsizei width, GLsizei height, GLsizei depth,
-                               GLenum unpackFormat, const TexImageSource& src);
-
+                               GLenum unpackFormat, const TexImageSource& src,
+                               const Maybe<GLsizei>& expectedImageSize);
     ////////////////////////////////////
 
 public:
     void CopyTexImage2D(GLenum target, GLint level, GLenum internalFormat, GLint x,
                         GLint y, GLsizei width, GLsizei height, GLint border);
 
     void CopyTexSubImage2D(GLenum target, GLint level, GLint xOffset,
                            GLint yOffset, GLint x, GLint y, GLsizei width,
@@ -1252,17 +1276,17 @@ protected:
     UniquePtr<webgl::TexUnpackBlob>
     FromDomElem(const char* funcName, TexImageTarget target, uint32_t width,
                 uint32_t height, uint32_t depth, const dom::Element& elem,
                 ErrorResult* const out_error);
 
     UniquePtr<webgl::TexUnpackBytes>
     FromCompressed(const char* funcName, TexImageTarget target, GLsizei rawWidth,
                    GLsizei rawHeight, GLsizei rawDepth, GLint border,
-                   const TexImageSource& src);
+                   const TexImageSource& src, const Maybe<GLsizei>& expectedImageSize);
 
 // -----------------------------------------------------------------------------
 // Vertices Feature (WebGLContextVertices.cpp)
     GLenum mPrimRestartTypeBytes;
 
 public:
     void DrawArrays(GLenum mode, GLint first, GLsizei count);
     void DrawArraysInstanced(GLenum mode, GLint first, GLsizei count,
--- a/dom/canvas/WebGLContextTextures.cpp
+++ b/dom/canvas/WebGLContextTextures.cpp
@@ -313,41 +313,41 @@ WebGLContext::TexParameter_base(GLenum r
 
 //////////////////////////////////////////////////////////////////////////////////////////
 // Uploads
 
 void
 WebGLContext::CompressedTexImage(const char* funcName, uint8_t funcDims, GLenum rawTarget,
                                  GLint level, GLenum internalFormat, GLsizei width,
                                  GLsizei height, GLsizei depth, GLint border,
-                                 const TexImageSource& src)
+                                 const TexImageSource& src, const Maybe<GLsizei>& expectedImageSize)
 {
     TexImageTarget target;
     WebGLTexture* tex;
     if (!ValidateTexImageTarget(this, funcName, funcDims, rawTarget, &target, &tex))
         return;
 
     tex->CompressedTexImage(funcName, target, level, internalFormat, width, height, depth,
-                            border, src);
+                            border, src, expectedImageSize);
 }
 
 void
 WebGLContext::CompressedTexSubImage(const char* funcName, uint8_t funcDims,
                                     GLenum rawTarget, GLint level, GLint xOffset,
                                     GLint yOffset, GLint zOffset, GLsizei width,
                                     GLsizei height, GLsizei depth, GLenum unpackFormat,
-                                    const TexImageSource& src)
+                                    const TexImageSource& src, const Maybe<GLsizei>& expectedImageSize)
 {
     TexImageTarget target;
     WebGLTexture* tex;
     if (!ValidateTexImageTarget(this, funcName, funcDims, rawTarget, &target, &tex))
         return;
 
     tex->CompressedTexSubImage(funcName, target, level, xOffset, yOffset, zOffset, width,
-                               height, depth, unpackFormat, src);
+                               height, depth, unpackFormat, src, expectedImageSize);
 }
 
 ////
 
 void
 WebGLContext::CopyTexImage2D(GLenum rawTarget, GLint level, GLenum internalFormat,
                              GLint x, GLint y, GLsizei width, GLsizei height,
                              GLint border)
--- a/dom/canvas/WebGLTexture.h
+++ b/dom/canvas/WebGLTexture.h
@@ -268,21 +268,22 @@ protected:
                   GLenum internalFormat, const webgl::PackingInfo& pi,
                   const webgl::TexUnpackBlob* blob);
     void TexSubImage(const char* funcName, TexImageTarget target, GLint level,
                      GLint xOffset, GLint yOffset, GLint zOffset,
                      const webgl::PackingInfo& pi, const webgl::TexUnpackBlob* blob);
 public:
     void CompressedTexImage(const char* funcName, TexImageTarget target, GLint level,
                             GLenum internalFormat, GLsizei width, GLsizei height,
-                            GLsizei depth, GLint border, const TexImageSource& src);
+                            GLsizei depth, GLint border, const TexImageSource& src,
+                            const Maybe<GLsizei>& expectedImageSize);
     void CompressedTexSubImage(const char* funcName, TexImageTarget target, GLint level,
                                GLint xOffset, GLint yOffset, GLint zOffset, GLsizei width,
                                GLsizei height, GLsizei depth, GLenum sizedUnpackFormat,
-                               const TexImageSource& src);
+                               const TexImageSource& src, const Maybe<GLsizei>& expectedImageSize);
 
     void CopyTexImage2D(TexImageTarget target, GLint level, GLenum internalFormat,
                         GLint x, GLint y, GLsizei width, GLsizei height, GLint border);
     void CopyTexSubImage(const char* funcName, TexImageTarget target, GLint level,
                          GLint xOffset, GLint yOffset, GLint zOffset, GLint x, GLint y,
                          GLsizei width, GLsizei height);
 
     ////////////////////////////////////
--- a/dom/canvas/WebGLTextureUpload.cpp
+++ b/dom/canvas/WebGLTextureUpload.cpp
@@ -181,17 +181,18 @@ FromView(WebGLContext* webgl, const char
         }
     }
     return MakeUnique<webgl::TexUnpackBytes>(webgl, target, width, height, depth,
                                              isClientData, bytes, availByteCount);
 }
 
 static UniquePtr<webgl::TexUnpackBytes>
 FromPboOffset(WebGLContext* webgl, const char* funcName, TexImageTarget target,
-              uint32_t width, uint32_t height, uint32_t depth, WebGLsizeiptr pboOffset)
+              uint32_t width, uint32_t height, uint32_t depth, WebGLsizeiptr pboOffset,
+              const Maybe<GLsizei>& expectedImageSize)
 {
     if (pboOffset < 0) {
         webgl->ErrorInvalidValue("%s: offset cannot be negative.", funcName);
         return nullptr;
     }
 
     const auto& buffer = webgl->ValidateBufferSelection(funcName,
                                                         LOCAL_GL_PIXEL_UNPACK_BUFFER);
@@ -199,17 +200,27 @@ FromPboOffset(WebGLContext* webgl, const
         return nullptr;
 
     size_t availBufferBytes = buffer->ByteLength();
     if (size_t(pboOffset) > availBufferBytes) {
         webgl->ErrorInvalidOperation("%s: Offset is passed end of buffer.", funcName);
         return nullptr;
     }
     availBufferBytes -= pboOffset;
-
+    if (expectedImageSize.isSome()) {
+        if (expectedImageSize.ref() < 0) {
+            webgl->ErrorInvalidValue("%s: ImageSize can't be less than 0.", funcName);
+            return nullptr;
+        }
+        if (size_t(expectedImageSize.ref()) != availBufferBytes) {
+            webgl->ErrorInvalidOperation("%s: ImageSize doesn't match the required upload byte size.", funcName);
+            return nullptr;
+        }
+        availBufferBytes = size_t(expectedImageSize.ref());
+    }
     const bool isClientData = false;
     const auto ptr = (const uint8_t*)pboOffset;
     return MakeUnique<webgl::TexUnpackBytes>(webgl, target, width, height, depth,
                                              isClientData, ptr, availBufferBytes);
 }
 
 static UniquePtr<webgl::TexUnpackBlob>
 FromImageBitmap(WebGLContext* webgl, const char* funcName, TexImageTarget target,
@@ -394,17 +405,17 @@ WebGLContext::From(const char* funcName,
     if (!ValidateExtents(this, funcName, rawWidth, rawHeight, rawDepth, border, &width,
                          &height, &depth))
     {
         return nullptr;
     }
 
     if (src.mPboOffset) {
         return FromPboOffset(this, funcName, target, width, height, depth,
-                             *(src.mPboOffset));
+                             *(src.mPboOffset), Nothing());
     }
 
     if (mBoundPixelUnpackBuffer) {
         ErrorInvalidOperation("%s: PIXEL_UNPACK_BUFFER must be null.", funcName);
         return nullptr;
     }
 
     if (src.mImageBitmap) {
@@ -1410,47 +1421,48 @@ WebGLTexture::TexSubImage(const char* fu
 }
 
 ////////////////////////////////////////
 // CompressedTex(Sub)Image
 
 UniquePtr<webgl::TexUnpackBytes>
 WebGLContext::FromCompressed(const char* funcName, TexImageTarget target,
                              GLsizei rawWidth, GLsizei rawHeight, GLsizei rawDepth,
-                             GLint border, const TexImageSource& src)
+                             GLint border, const TexImageSource& src,
+                             const Maybe<GLsizei>& expectedImageSize)
 {
     uint32_t width, height, depth;
     if (!ValidateExtents(this, funcName, rawWidth, rawHeight, rawDepth, border, &width,
                          &height, &depth))
     {
         return nullptr;
     }
 
     if (src.mPboOffset) {
         return FromPboOffset(this, funcName, target, width, height, depth,
-                             *(src.mPboOffset));
+                             *(src.mPboOffset), expectedImageSize);
     }
 
     if (mBoundPixelUnpackBuffer) {
         ErrorInvalidOperation("%s: PIXEL_UNPACK_BUFFER must be null.", funcName);
         return nullptr;
     }
 
     return FromView(this, funcName, target, width, height, depth, src.mView,
                     src.mViewElemOffset, src.mViewElemLengthOverride);
 }
 
 void
 WebGLTexture::CompressedTexImage(const char* funcName, TexImageTarget target, GLint level,
                                  GLenum internalFormat, GLsizei rawWidth,
                                  GLsizei rawHeight, GLsizei rawDepth, GLint border,
-                                 const TexImageSource& src)
+                                 const TexImageSource& src, const Maybe<GLsizei>& expectedImageSize)
 {
     const auto blob = mContext->FromCompressed(funcName, target, rawWidth, rawHeight,
-                                               rawDepth, border, src);
+                                               rawDepth, border, src, expectedImageSize);
     if (!blob)
         return;
 
     ////////////////////////////////////
     // Get dest info
 
     WebGLTexture::ImageInfo* imageInfo;
     if (!ValidateTexImageSpecification(funcName, target, level, blob->mWidth,
@@ -1495,16 +1507,18 @@ WebGLTexture::CompressedTexImage(const c
     {
         return;
     }
 
     ////////////////////////////////////
     // Do the thing!
 
     mContext->gl->MakeCurrent();
+    const ScopedLazyBind bindPBO(mContext->gl, LOCAL_GL_PIXEL_UNPACK_BUFFER,
+                                 mContext->mBoundPixelUnpackBuffer);
 
     // Warning: Possibly shared memory.  See bug 1225033.
     GLenum error = DoCompressedTexImage(mContext->gl, target, level, internalFormat,
                                         blob->mWidth, blob->mHeight, blob->mDepth,
                                         blob->mAvailBytes, blob->mPtr);
     mContext->OnDataAllocCall();
     if (error == LOCAL_GL_OUT_OF_MEMORY) {
         mContext->ErrorOutOfMemory("%s: Ran out of memory during upload.", funcName);
@@ -1548,21 +1562,21 @@ IsSubImageBlockAligned(const webgl::Comp
     return true;
 }
 
 void
 WebGLTexture::CompressedTexSubImage(const char* funcName, TexImageTarget target,
                                     GLint level, GLint xOffset, GLint yOffset,
                                     GLint zOffset, GLsizei rawWidth, GLsizei rawHeight,
                                     GLsizei rawDepth, GLenum sizedUnpackFormat,
-                                    const TexImageSource& src)
+                                    const TexImageSource& src, const Maybe<GLsizei>& expectedImageSize)
 {
     const GLint border = 0;
     const auto blob = mContext->FromCompressed(funcName, target, rawWidth, rawHeight,
-                                               rawDepth, border, src);
+                                               rawDepth, border, src, expectedImageSize);
     if (!blob)
         return;
 
     ////////////////////////////////////
     // Get dest info
 
     WebGLTexture::ImageInfo* imageInfo;
     if (!ValidateTexImageSelection(funcName, target, level, xOffset, yOffset, zOffset,
@@ -1646,16 +1660,19 @@ WebGLTexture::CompressedTexSubImage(cons
     if (!EnsureImageDataInitializedForUpload(this, funcName, target, level, xOffset,
                                              yOffset, zOffset, blob->mWidth,
                                              blob->mHeight, blob->mDepth, imageInfo,
                                              &uploadWillInitialize))
     {
         return;
     }
 
+    const ScopedLazyBind bindPBO(mContext->gl, LOCAL_GL_PIXEL_UNPACK_BUFFER,
+                                 mContext->mBoundPixelUnpackBuffer);
+
     // Warning: Possibly shared memory.  See bug 1225033.
     GLenum error = DoCompressedTexSubImage(mContext->gl, target, level, xOffset, yOffset,
                                            zOffset, blob->mWidth, blob->mHeight,
                                            blob->mDepth, sizedUnpackFormat,
                                            blob->mAvailBytes, blob->mPtr);
     if (error == LOCAL_GL_OUT_OF_MEMORY) {
         mContext->ErrorOutOfMemory("%s: Ran out of memory during upload.", funcName);
         return;
--- a/dom/webidl/WebGL2RenderingContext.webidl
+++ b/dom/webidl/WebGL2RenderingContext.webidl
@@ -506,38 +506,38 @@ interface WebGL2RenderingContextBase
     void texSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset,
                        GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type,
                        ArrayBufferView? srcData, optional GLuint srcOffset = 0);
 
     void copyTexSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset,
                            GLint x, GLint y, GLsizei width, GLsizei height);
 
     void compressedTexImage2D(GLenum target, GLint level, GLenum internalformat, GLsizei width,
-                              GLsizei height, GLint border, GLintptr offset);
+                              GLsizei height, GLint border, GLsizei imageSize,  GLintptr offset);
     void compressedTexImage2D(GLenum target, GLint level, GLenum internalformat, GLsizei width,
                               GLsizei height, GLint border, ArrayBufferView srcData,
                               optional GLuint srcOffset = 0, optional GLuint srcLengthOverride = 0);
 
     void compressedTexImage3D(GLenum target, GLint level, GLenum internalformat, GLsizei width,
-                              GLsizei height, GLsizei depth, GLint border, GLintptr offset);
+                              GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, GLintptr offset);
     void compressedTexImage3D(GLenum target, GLint level, GLenum internalformat, GLsizei width,
                               GLsizei height, GLsizei depth, GLint border, ArrayBufferView srcData,
                               optional GLuint srcOffset = 0, optional GLuint srcLengthOverride = 0);
 
     void compressedTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset,
-                                 GLsizei width, GLsizei height, GLenum format, GLintptr offset);
+                                 GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, GLintptr offset);
     void compressedTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset,
                                  GLsizei width, GLsizei height, GLenum format,
                                  ArrayBufferView srcData,
                                  optional GLuint srcOffset = 0,
                                  optional GLuint srcLengthOverride = 0);
 
     void compressedTexSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset,
                                  GLint zoffset, GLsizei width, GLsizei height, GLsizei depth,
-                                 GLenum format, GLintptr offset);
+                                 GLenum format, GLsizei imageSize, GLintptr offset);
     void compressedTexSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset,
                                  GLint zoffset, GLsizei width, GLsizei height, GLsizei depth,
                                  GLenum format, ArrayBufferView srcData,
                                  optional GLuint srcOffset = 0,
                                  optional GLuint srcLengthOverride = 0);
 
     /* Programs and shaders */
     [WebGLHandlesContextLoss] GLint getFragDataLocation(WebGLProgram program, DOMString name);