--- 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);