--- a/dom/canvas/WebGL2Context.h
+++ b/dom/canvas/WebGL2Context.h
@@ -87,41 +87,77 @@ 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);
+ ////
+
+private:
+ void TexImage3D(GLenum target, GLint level, GLenum internalFormat, GLsizei width,
+ GLsizei height, GLsizei depth, GLint border, GLenum unpackFormat,
+ GLenum unpackType, const dom::ArrayBufferView* srcView,
+ GLuint srcElemOffset);
+
+public:
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>& data);
+ GLenum unpackType,
+ const dom::Nullable<dom::ArrayBufferView>& maybeSrc)
+ {
+ const dom::ArrayBufferView* srcView = nullptr;
+ if (!maybeSrc.IsNull()) {
+ srcView = &maybeSrc.Value();
+ }
+ TexImage3D(target, level, internalFormat, width, height, depth, border,
+ unpackFormat, unpackType, srcView, 0);
+ }
+
+ void TexImage3D(GLenum target, GLint level, GLenum internalFormat, GLsizei width,
+ GLsizei height, GLsizei depth, GLint border, GLenum unpackFormat,
+ GLenum unpackType, const dom::ArrayBufferView& srcView,
+ GLuint srcElemOffset)
+ {
+ TexImage3D(target, level, internalFormat, width, height, depth, border,
+ unpackFormat, unpackType, &srcView, srcElemOffset);
+ }
+
+ ////
void TexSubImage3D(GLenum target, GLint level, GLint xOffset, GLint yOffset,
GLint zOffset, GLsizei width, GLsizei height, GLsizei depth,
GLenum unpackFormat, GLenum unpackType,
- const dom::ArrayBufferView& data, ErrorResult&);
+ const dom::ArrayBufferView& srcView, GLuint srcElemOffset,
+ ErrorResult&);
void TexSubImage3D(GLenum target, GLint level, GLint xOffset, GLint yOffset,
GLint zOffset, GLenum unpackFormat, GLenum unpackType,
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);
+ GLsizei width, GLsizei height, GLsizei depth, GLint border,
+ const dom::ArrayBufferView& srcView, GLuint srcElemOffset);
void CompressedTexSubImage3D(GLenum target, GLint level, GLint xOffset, GLint yOffset,
GLint zOffset, GLsizei width, GLsizei height,
GLsizei depth, GLenum sizedUnpackFormat,
- const dom::ArrayBufferView& data);
+ const dom::ArrayBufferView& srcView,
+ GLuint srcElemOffset);
////////////////
// Texture PBOs
void TexImage2D(GLenum texImageTarget, GLint level, GLenum internalFormat,
GLsizei width, GLsizei height, GLint border, GLenum unpackFormat,
GLenum unpackType, WebGLsizeiptr offset, ErrorResult&);
--- a/dom/canvas/WebGL2ContextTextures.cpp
+++ b/dom/canvas/WebGL2ContextTextures.cpp
@@ -40,48 +40,44 @@ WebGL2Context::TexStorage3D(GLenum rawTe
tex->TexStorage(funcName, target, levels, internalFormat, width, height, depth);
}
void
WebGL2Context::TexImage3D(GLenum rawTexImageTarget, GLint level, GLenum internalFormat,
GLsizei width, GLsizei height, GLsizei depth, GLint border,
GLenum unpackFormat, GLenum unpackType,
- const dom::Nullable<dom::ArrayBufferView>& maybeView)
+ const dom::ArrayBufferView>* srcView, GLuint srcElemOffset)
{
const char funcName[] = "texImage3D";
const uint8_t funcDims = 3;
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, view);
+ unpackType, view, srcElemOffset);
}
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::ArrayBufferView& view, ErrorResult&)
+ const dom::ArrayBufferView& srcView, GLuint srcElemOffset,
+ ErrorResult&)
{
const char funcName[] = "texSubImage3D";
const uint8_t funcDims = 3;
TexImageTarget target;
WebGLTexture* tex;
if (!ValidateTexImageTarget(this, funcName, funcDims, rawTexImageTarget, &target,
&tex))
@@ -89,17 +85,17 @@ 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, &view);
+ unpackType, &srcView, srcElemOffset);
}
void
WebGL2Context::TexSubImage3D(GLenum rawTexImageTarget, GLint level, GLint xOffset,
GLint yOffset, GLint zOffset, GLenum unpackFormat,
GLenum unpackType, const dom::ImageData& imageData,
ErrorResult&)
{
@@ -142,53 +138,55 @@ WebGL2Context::TexSubImage3D(GLenum rawT
tex->TexOrSubImage(isSubImage, funcName, target, level, internalFormat, xOffset,
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)
+ const dom::ArrayBufferView& srcView,
+ GLuint srcElemOffset)
{
const char funcName[] = "compressedTexImage3D";
const uint8_t funcDims = 3;
TexImageTarget target;
WebGLTexture* tex;
if (!ValidateTexImageTarget(this, funcName, funcDims, rawTexImageTarget, &target,
&tex))
{
return;
}
tex->CompressedTexImage(funcName, target, level, internalFormat, width, height, depth,
- border, view);
+ border, view, srcElemOffset);
}
void
WebGL2Context::CompressedTexSubImage3D(GLenum rawTexImageTarget, GLint level,
GLint xOffset, GLint yOffset, GLint zOffset,
GLsizei width, GLsizei height, GLsizei depth,
GLenum sizedUnpackFormat,
- const dom::ArrayBufferView& view)
+ const dom::ArrayBufferView& srcView,
+ GLuint srcElemOffset)
{
const char funcName[] = "compressedTexSubImage3D";
const uint8_t funcDims = 3;
TexImageTarget target;
WebGLTexture* tex;
if (!ValidateTexImageTarget(this, funcName, funcDims, rawTexImageTarget, &target,
&tex))
{
return;
}
tex->CompressedTexSubImage(funcName, target, level, xOffset, yOffset, zOffset, width,
- height, depth, sizedUnpackFormat, view);
+ height, depth, sizedUnpackFormat, view, srcElemOffset);
}
void
WebGL2Context::CopyTexSubImage3D(GLenum rawTexImageTarget, GLint level, GLint xOffset,
GLint yOffset, GLint zOffset, GLint x, GLint y,
GLsizei width, GLsizei height)
{
const char funcName[] = "copyTexSubImage3D";
--- a/dom/canvas/WebGLContext.h
+++ b/dom/canvas/WebGLContext.h
@@ -882,17 +882,31 @@ public:
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&);
+ ErrorResult& out_error)
+ {
+ if (IsContextLost())
+ return;
+
+ TexImage2D(texImageTarget, level, internalFormat, width, height, border,
+ unpackFormat, unpackType, maybeView, 0, out_error);
+ }
+
+ void TexImage2D(GLenum texImageTarget, GLint level, GLenum internalFormat,
+ GLsizei width, GLsizei height, GLint border, GLenum unpackFormat,
+ GLenum unpackType,
+ const dom::Nullable<dom::ArrayBufferView>& maybeSrc,
+ GLuint srcElemOffset, ErrorResult&);
+
protected:
void TexImage2D(GLenum texImageTarget, GLint level, GLenum internalFormat,
GLenum unpackFormat, GLenum unpackType,
const dom::ImageData& imageData, ErrorResult& out_error);
public:
void TexImage2D(GLenum texImageTarget, GLint level, GLenum internalFormat,
GLenum unpackFormat, GLenum unpackType, const dom::Element& elem,
ErrorResult& out_error);
@@ -907,58 +921,72 @@ protected:
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
+ // dom::ImageData
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);
+ if (IsContextLost())
return;
- }
+
+ if (!imageData)
+ return ErrorInvalidValue("%s: `data` must not be null.", funcName);
+
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&)
- {
- 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());
- }
-
- 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,
*imageData, out_error);
}
+ ////
+ // ArrayBufferView
+
+ void TexSubImage2D(GLenum texImageTarget, GLint level, GLint xOffset, GLint yOffset,
+ GLsizei width, GLsizei height, GLenum unpackFormat,
+ GLenum unpackType,
+ const dom::Nullable<dom::ArrayBufferView>& maybeSrc,
+ ErrorResult& out_error)
+ {
+ const char funcName[] = "texSubImage2D";
+ if (IsContextLost())
+ return;
+
+ if (maybeSrc.IsNull())
+ return ErrorInvalidValue("%s: `data` must not be null.", funcName);
+
+ TexSubImage2D(texImageTarget, level, xOffset, yOffset, width, height,
+ unpackFormat, unpackType, maybeView.Value(), 0, out_error);
+ }
+
+ void TexSubImage2D(GLenum texImageTarget, GLint level, GLint xOffset, GLint yOffset,
+ GLsizei width, GLsizei height, GLenum unpackFormat,
+ GLenum unpackType,
+ const dom::ArrayBufferView& srcView, GLuint srcElemOffset,
+ ErrorResult&);
+
//////
// WebGLTextureUpload.cpp
public:
bool ValidateUnpackPixels(const char* funcName, uint32_t fullRows,
uint32_t tailPixels, webgl::TexUnpackBlob* blob);
protected:
bool ValidateTexImageSpecification(const char* funcName, uint8_t funcDims,
--- a/dom/canvas/WebGLTexture.h
+++ b/dom/canvas/WebGLTexture.h
@@ -231,17 +231,17 @@ 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::ArrayBufferView* view);
+ const dom::ArrayBufferView* srcView, GLuint srcElemOffset);
void TexOrSubImage(bool isSubImage, const char* funcName, TexImageTarget target,
GLint level, GLenum internalFormat, GLint xOffset, GLint yOffset,
GLint zOffset, GLenum unpackFormat, GLenum unpackType,
const dom::ImageData& imageData);
void TexOrSubImage(bool isSubImage, const char* funcName, TexImageTarget target,
GLint level, GLenum internalFormat, GLint xOffset, GLint yOffset,
@@ -283,21 +283,21 @@ protected:
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 dom::ArrayBufferView& view);
+ const dom::ArrayBufferView& srcView, GLuint srcElemOffset);
void CompressedTexSubImage(const char* funcName, TexImageTarget target, GLint level,
GLint xOffset, GLint yOffset, GLint zOffset, GLsizei width,
GLsizei height, GLsizei depth, GLenum sizedUnpackFormat,
- const dom::ArrayBufferView& view);
+ const dom::ArrayBufferView& srcView, GLuint srcElemOffset);
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
@@ -178,17 +178,17 @@ WebGLContext::ValidateUnpackPixels(const
funcName, fullRowsNeeded.value(), usedPixelsPerRow.value(),
fullRows, tailPixels);
return false;
}
static bool
ValidateUnpackBytes(WebGLContext* webgl, const char* funcName, uint32_t width,
uint32_t height, uint32_t depth, const webgl::PackingInfo& pi,
- uint32_t byteCount, webgl::TexUnpackBlob* blob)
+ size_t byteCount, webgl::TexUnpackBlob* blob)
{
if (!width || !height || !depth)
return true;
const auto bytesPerPixel = webgl::BytesPerPixel(pi);
const auto bytesPerRow = CheckedUint32(blob->mRowLength) * bytesPerPixel;
const auto rowStride = RoundUpToMultipleOf(bytesPerRow, blob->mAlignment);
@@ -235,46 +235,48 @@ 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::ArrayBufferView* view)
+ const dom::ArrayBufferView* srcView, GLuint srcElemOffset)
{
uint32_t width, height, depth;
if (!ValidateExtents(mContext, funcName, rawWidth, rawHeight, rawDepth, border,
&width, &height, &depth))
{
return;
}
const bool usePBOs = false;
webgl::PackingInfo pi;
if (!mContext->ValidateUnpackInfo(funcName, usePBOs, unpackFormat, unpackType, &pi))
return;
////
const uint8_t* bytes = nullptr;
- uint32_t byteCount = 0;
+ size_t byteCount = 0;
- if (view) {
- view->ComputeLengthAndData();
- bytes = view->DataAllowShared();
- byteCount = view->LengthAllowShared();
-
- const auto& jsType = view->Type();
+ if (srcView) {
+ const auto& jsType = srcView->Type();
if (!DoesJSTypeMatchUnpackType(pi.type, jsType)) {
mContext->ErrorInvalidOperation("%s: `pixels` not compatible with `type`.",
funcName);
return;
}
+
+ if (!mContext->ValidateArrayBufferView(funcName, *srcView, srcElemOffset, 0,
+ &bytes, &byteCount))
+ {
+ return;
+ }
} 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);
@@ -1446,17 +1448,18 @@ WebGLTexture::TexSubImage(const char* fu
////////////////////////////////////////
// CompressedTex(Sub)Image
void
WebGLTexture::CompressedTexImage(const char* funcName, TexImageTarget target, GLint level,
GLenum internalFormat, GLsizei rawWidth,
GLsizei rawHeight, GLsizei rawDepth, GLint border,
- const dom::ArrayBufferView& view)
+ const dom::ArrayBufferView& srcView,
+ GLuint srcElemOffset)
{
uint32_t width, height, depth;
if (!ValidateExtents(mContext, funcName, rawWidth, rawHeight, rawDepth, border,
&width, &height, &depth))
{
return;
}
@@ -1486,22 +1489,26 @@ WebGLTexture::CompressedTexImage(const c
}
if (!ValidateTargetForFormat(funcName, mContext, target, format))
return;
////////////////////////////////////
// Get source info
- view.ComputeLengthAndData();
- const void* data = view.DataAllowShared();
- size_t dataSize = view.LengthAllowShared();
+ uint8_t* bytes;
+ size_t byteLen;
+ if (!mContext->ValidateArrayBufferView(funcName, srcView, srcElemOffset, 0, &bytes,
+ &byteLen))
+ {
+ return;
+ }
if (!ValidateCompressedTexUnpack(mContext, funcName, width, height, depth, format,
- dataSize))
+ byteLen))
{
return;
}
////////////////////////////////////
// Check that source is compatible with dest
if (!ValidateCompressedTexImageRestrictions(funcName, mContext, target, level, format,
@@ -1512,17 +1519,17 @@ WebGLTexture::CompressedTexImage(const c
////////////////////////////////////
// Do the thing!
mContext->gl->MakeCurrent();
// Warning: Possibly shared memory. See bug 1225033.
GLenum error = DoCompressedTexImage(mContext->gl, target, level, internalFormat,
- width, height, depth, dataSize, data);
+ width, height, depth, byteLen, bytes);
if (error == LOCAL_GL_OUT_OF_MEMORY) {
mContext->ErrorOutOfMemory("%s: Ran out of memory during upload.", funcName);
return;
}
if (error) {
MOZ_RELEASE_ASSERT(false, "GFX: We should have caught all other errors.");
mContext->GenerateWarning("%s: Unexpected error during texture upload. Context"
" lost.",
@@ -1559,17 +1566,18 @@ 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 dom::ArrayBufferView& view)
+ const dom::ArrayBufferView& srcView,
+ GLuint srcElemOffset)
{
uint32_t width, height, depth;
if (!ValidateExtents(mContext, funcName, rawWidth, rawHeight, rawDepth, 0, &width,
&height, &depth))
{
return;
}
@@ -1585,19 +1593,23 @@ WebGLTexture::CompressedTexSubImage(cons
MOZ_ASSERT(imageInfo);
auto dstUsage = imageInfo->mFormat;
auto dstFormat = dstUsage->format;
////////////////////////////////////
// Get source info
- view.ComputeLengthAndData();
- size_t dataSize = view.LengthAllowShared();
- const void* data = view.DataAllowShared();
+ uint8_t* bytes;
+ size_t byteLen;
+ if (!mContext->ValidateArrayBufferView(funcName, srcView, srcElemOffset, 0, &bytes,
+ &byteLen))
+ {
+ return;
+ }
auto srcUsage = mContext->mFormatUsage->GetSizedTexUsage(sizedUnpackFormat);
if (!srcUsage->format->compression) {
mContext->ErrorInvalidEnum("%s: Specified format must be compressed.", funcName);
return;
}
if (srcUsage != dstUsage) {
@@ -1605,17 +1617,17 @@ WebGLTexture::CompressedTexSubImage(cons
" existing texture image.",
funcName);
return;
}
auto format = srcUsage->format;
MOZ_ASSERT(format == dstFormat);
if (!ValidateCompressedTexUnpack(mContext, funcName, width, height, depth, format,
- dataSize))
+ byteLen))
{
return;
}
////////////////////////////////////
// Check that source is compatible with dest
switch (format->compression->family) {
@@ -1664,17 +1676,17 @@ WebGLTexture::CompressedTexSubImage(cons
imageInfo, &uploadWillInitialize))
{
return;
}
// Warning: Possibly shared memory. See bug 1225033.
GLenum error = DoCompressedTexSubImage(mContext->gl, target, level, xOffset, yOffset,
zOffset, width, height, depth,
- sizedUnpackFormat, dataSize, data);
+ sizedUnpackFormat, byteLen, bytes);
if (error == LOCAL_GL_OUT_OF_MEMORY) {
mContext->ErrorOutOfMemory("%s: Ran out of memory during upload.", funcName);
return;
}
if (error) {
MOZ_RELEASE_ASSERT(false, "GFX: We should have caught all other errors.");
mContext->GenerateWarning("%s: Unexpected error during texture upload. Context"
" lost.",