--- a/dom/canvas/TexUnpackBlob.cpp
+++ b/dom/canvas/TexUnpackBlob.cpp
@@ -126,16 +126,96 @@ FormatForPackingInfo(const PackingInfo&
break;
}
return WebGLTexelFormat::FormatNotSupportingAnyConversion;
}
////////////////////
+static bool
+ValidateUnpackPixels(WebGLContext* webgl, const char* funcName, uint32_t fullRows,
+ uint32_t tailPixels, webgl::TexUnpackBlob* blob)
+{
+ if (!blob->mWidth || !blob->mHeight || !blob->mDepth)
+ return true;
+
+ const auto usedPixelsPerRow = CheckedUint32(blob->mSkipPixels) + blob->mWidth;
+ if (!usedPixelsPerRow.isValid() || usedPixelsPerRow.value() > blob->mRowLength) {
+ webgl->ErrorInvalidOperation("%s: UNPACK_SKIP_PIXELS + width >"
+ " UNPACK_ROW_LENGTH.",
+ funcName);
+ return false;
+ }
+
+ if (blob->mHeight > blob->mImageHeight) {
+ webgl->ErrorInvalidOperation("%s: height > UNPACK_IMAGE_HEIGHT.", funcName);
+ return false;
+ }
+
+ //////
+
+ // The spec doesn't bound SKIP_ROWS + height <= IMAGE_HEIGHT, unfortunately.
+ auto skipFullRows = CheckedUint32(blob->mSkipImages) * blob->mImageHeight;
+ skipFullRows += blob->mSkipRows;
+
+ MOZ_ASSERT(blob->mDepth >= 1);
+ MOZ_ASSERT(blob->mHeight >= 1);
+ auto usedFullRows = CheckedUint32(blob->mDepth - 1) * blob->mImageHeight;
+ usedFullRows += blob->mHeight - 1; // Full rows in the final image, excluding the tail.
+
+ const auto fullRowsNeeded = skipFullRows + usedFullRows;
+ if (!fullRowsNeeded.isValid()) {
+ webgl->ErrorOutOfMemory("%s: Invalid calculation for required row count.",
+ funcName);
+ return false;
+ }
+
+ if (fullRows > fullRowsNeeded.value())
+ return true;
+
+ if (fullRows == fullRowsNeeded.value() && tailPixels >= usedPixelsPerRow.value()) {
+ blob->mNeedsExactUpload = true;
+ return true;
+ }
+
+ webgl->ErrorInvalidOperation("%s: Desired upload requires more data than is"
+ " available: (%u rows plus %u pixels needed, %u rows"
+ " plus %u pixels available)",
+ funcName, fullRowsNeeded.value(),
+ usedPixelsPerRow.value(), fullRows, tailPixels);
+ return false;
+}
+
+static bool
+ValidateUnpackBytes(WebGLContext* webgl, const char* funcName,
+ const webgl::PackingInfo& pi, size_t availByteCount,
+ webgl::TexUnpackBlob* blob)
+{
+ if (!blob->mWidth || !blob->mHeight || !blob->mDepth)
+ return true;
+
+ const auto bytesPerPixel = webgl::BytesPerPixel(pi);
+ const auto bytesPerRow = CheckedUint32(blob->mRowLength) * bytesPerPixel;
+ const auto rowStride = RoundUpToMultipleOf(bytesPerRow, blob->mAlignment);
+
+ const auto fullRows = availByteCount / rowStride;
+ if (!fullRows.isValid()) {
+ webgl->ErrorOutOfMemory("%s: Unacceptable upload size calculated.");
+ return false;
+ }
+
+ const auto bodyBytes = fullRows.value() * rowStride.value();
+ const auto tailPixels = (availByteCount - bodyBytes) / bytesPerPixel;
+
+ return ValidateUnpackPixels(webgl, funcName, fullRows.value(), tailPixels, blob);
+}
+
+////////////////////
+
static uint32_t
ZeroOn2D(TexImageTarget target, uint32_t val)
{
return (IsTarget3D(target) ? val : 0);
}
static uint32_t
FallbackOnZero(uint32_t val, uint32_t fallback)
@@ -326,25 +406,36 @@ DoTexOrSubImage(bool isSubImage, gl::GLC
}
}
//////////////////////////////////////////////////////////////////////////////////////////
// TexUnpackBytes
TexUnpackBytes::TexUnpackBytes(const WebGLContext* webgl, TexImageTarget target,
uint32_t width, uint32_t height, uint32_t depth,
- bool isClientData, const uint8_t* ptr)
+ bool isClientData, const uint8_t* ptr, size_t availBytes)
: TexUnpackBlob(webgl, target,
FallbackOnZero(webgl->mPixelStore_UnpackRowLength, width), width,
height, depth, false)
, mIsClientData(isClientData)
, mPtr(ptr)
+ , mAvailBytes(availBytes)
{ }
bool
+TexUnpackBytes::Validate(WebGLContext* webgl, const char* funcName,
+ const webgl::PackingInfo& pi)
+{
+ if (mIsClientData && !mPtr)
+ return true;
+
+ return ValidateUnpackBytes(webgl, funcName, pi, mAvailBytes, this);
+}
+
+bool
TexUnpackBytes::TexOrSubImage(bool isSubImage, bool needsRespec, const char* funcName,
WebGLTexture* tex, TexImageTarget target, GLint level,
const webgl::DriverUnpackInfo* dui, GLint xOffset,
GLint yOffset, GLint zOffset, GLenum* const out_error) const
{
WebGLContext* webgl = tex->mContext;
const auto pi = dui->ToPacking();
@@ -466,16 +557,24 @@ TexUnpackImage::TexUnpackImage(const Web
isAlphaPremult)
, mImage(image)
{ }
TexUnpackImage::~TexUnpackImage()
{ }
bool
+TexUnpackImage::Validate(WebGLContext* webgl, const char* funcName,
+ const webgl::PackingInfo& pi)
+{
+ const auto& fullRows = mImage->GetSize().height;
+ return ValidateUnpackPixels(webgl, funcName, fullRows, 0, this);
+}
+
+bool
TexUnpackImage::TexOrSubImage(bool isSubImage, bool needsRespec, const char* funcName,
WebGLTexture* tex, TexImageTarget target, GLint level,
const webgl::DriverUnpackInfo* dui, GLint xOffset,
GLint yOffset, GLint zOffset, GLenum* const out_error) const
{
MOZ_ASSERT_IF(needsRespec, !isSubImage);
WebGLContext* webgl = tex->mContext;
@@ -621,16 +720,24 @@ GetFormatForSurf(gfx::SourceSurface* sur
default:
return false;
}
}
//////////
bool
+TexUnpackSurface::Validate(WebGLContext* webgl, const char* funcName,
+ const webgl::PackingInfo& pi)
+{
+ const auto& fullRows = mSurf->GetSize().height;
+ return ValidateUnpackPixels(webgl, funcName, fullRows, 0, this);
+}
+
+bool
TexUnpackSurface::TexOrSubImage(bool isSubImage, bool needsRespec, const char* funcName,
WebGLTexture* tex, TexImageTarget target, GLint level,
const webgl::DriverUnpackInfo* dstDUI, GLint xOffset,
GLint yOffset, GLint zOffset,
GLenum* const out_error) const
{
WebGLContext* webgl = tex->mContext;
--- a/dom/canvas/TexUnpackBlob.h
+++ b/dom/canvas/TexUnpackBlob.h
@@ -67,34 +67,40 @@ protected:
WebGLTexelFormat srcFormat,
const webgl::DriverUnpackInfo* dstDUI,
const uint8_t** const out_bytes,
UniqueBuffer* const out_anchoredBuffer) const;
public:
virtual bool HasData() const { return true; }
+ virtual bool Validate(WebGLContext* webgl, const char* funcName,
+ const webgl::PackingInfo& pi) = 0;
virtual bool TexOrSubImage(bool isSubImage, bool needsRespec, const char* funcName,
WebGLTexture* tex, TexImageTarget target, GLint level,
const webgl::DriverUnpackInfo* dui, GLint xOffset,
GLint yOffset, GLint zOffset,
GLenum* const out_error) const = 0;
};
class TexUnpackBytes final : public TexUnpackBlob
{
public:
const bool mIsClientData;
const uint8_t* const mPtr;
+ const size_t mAvailBytes;
TexUnpackBytes(const WebGLContext* webgl, TexImageTarget target, uint32_t width,
- uint32_t height, uint32_t depth, bool isClientData, const uint8_t* ptr);
+ uint32_t height, uint32_t depth, bool isClientData, const uint8_t* ptr,
+ size_t availBytes);
virtual bool HasData() const override { return !mIsClientData || bool(mPtr); }
+ virtual bool Validate(WebGLContext* webgl, const char* funcName,
+ const webgl::PackingInfo& pi) override;
virtual bool TexOrSubImage(bool isSubImage, bool needsRespec, const char* funcName,
WebGLTexture* tex, TexImageTarget target, GLint level,
const webgl::DriverUnpackInfo* dui, GLint xOffset,
GLint yOffset, GLint zOffset,
GLenum* const out_error) const override;
};
class TexUnpackImage final : public TexUnpackBlob
@@ -103,32 +109,36 @@ public:
const RefPtr<layers::Image> mImage;
TexUnpackImage(const WebGLContext* webgl, TexImageTarget target, uint32_t width,
uint32_t height, uint32_t depth, layers::Image* image,
bool isAlphaPremult);
~TexUnpackImage(); // Prevent needing to define layers::Image in the header.
+ virtual bool Validate(WebGLContext* webgl, const char* funcName,
+ const webgl::PackingInfo& pi) override;
virtual bool TexOrSubImage(bool isSubImage, bool needsRespec, const char* funcName,
WebGLTexture* tex, TexImageTarget target, GLint level,
const webgl::DriverUnpackInfo* dui, GLint xOffset,
GLint yOffset, GLint zOffset,
GLenum* const out_error) const override;
};
class TexUnpackSurface final : public TexUnpackBlob
{
public:
const RefPtr<gfx::DataSourceSurface> mSurf;
TexUnpackSurface(const WebGLContext* webgl, TexImageTarget target, uint32_t width,
uint32_t height, uint32_t depth, gfx::DataSourceSurface* surf,
bool isAlphaPremult);
+ virtual bool Validate(WebGLContext* webgl, const char* funcName,
+ const webgl::PackingInfo& pi) override;
virtual bool TexOrSubImage(bool isSubImage, bool needsRespec, const char* funcName,
WebGLTexture* tex, TexImageTarget target, GLint level,
const webgl::DriverUnpackInfo* dui, GLint xOffset,
GLint yOffset, GLint zOffset,
GLenum* const out_error) const override;
};
} // namespace webgl
--- a/dom/canvas/WebGL2Context.h
+++ b/dom/canvas/WebGL2Context.h
@@ -83,94 +83,148 @@ public:
void RenderbufferStorageMultisample(GLenum target, GLsizei samples, GLenum internalformat,
GLsizei width, GLsizei height);
// -------------------------------------------------------------------------
// Texture objects - WebGL2ContextTextures.cpp
void TexStorage2D(GLenum target, GLsizei levels, GLenum internalFormat, GLsizei width,
- GLsizei height);
+ GLsizei height)
+ {
+ const char funcName[] = "TexStorage2D";
+ const uint8_t funcDims = 2;
+ const GLsizei depth = 1;
+ TexStorage(funcName, funcDims, target, levels, internalFormat, width, height,
+ depth);
+ }
+
void TexStorage3D(GLenum target, GLsizei levels, GLenum internalFormat, GLsizei width,
- GLsizei height, GLsizei depth);
+ GLsizei height, GLsizei depth)
+ {
+ const char funcName[] = "TexStorage3D";
+ const uint8_t funcDims = 3;
+ TexStorage(funcName, funcDims, target, levels, internalFormat, width, height,
+ depth);
+ }
+
+protected:
+ void TexStorage(const char* funcName, uint8_t funcDims, GLenum target, GLsizei levels,
+ GLenum internalFormat, GLsizei width, GLsizei height, GLsizei depth);
+
+ ////////////////////////////////////
- ////
+public:
+ 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)
+ {
+ const char funcName[] = "compressedTexImage3D";
+ const uint8_t funcDims = 3;
+ const TexImageSourceAdapter src(anySrc, viewElemOffset);
+ CompressedTexImage(funcName, funcDims, target, level, internalFormat, width,
+ height, depth, border, src);
+ }
-private:
+ 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)
+ {
+ const char funcName[] = "compressedTexSubImage3D";
+ const uint8_t funcDims = 3;
+ const TexImageSourceAdapter src(anySrc, viewElemOffset);
+ CompressedTexSubImage(funcName, funcDims, target, level, xOffset, yOffset,
+ zOffset, width, height, depth, unpackFormat, src);
+ }
+
+ ////////////////////////////////////
+
+ void CopyTexSubImage3D(GLenum target, GLint level, GLint xOffset, GLint yOffset,
+ GLint zOffset, GLint x, GLint y, GLsizei width,
+ GLsizei height)
+ {
+ const char funcName[] = "copyTexSubImage3D";
+ const uint8_t funcDims = 3;
+ CopyTexSubImage(funcName, funcDims, target, level, xOffset, yOffset, zOffset,
+ x, y, width, height);
+ }
+
+ ////////////////////////////////////
+
+ template<typename T>
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>& maybeSrc, ErrorResult&)
+ GLenum unpackType, const T& anySrc, ErrorResult& out_error)
{
- const dom::ArrayBufferView* srcView = nullptr;
- if (!maybeSrc.IsNull()) {
- srcView = &maybeSrc.Value();
- }
+ const TexImageSourceAdapter src(anySrc, &out_error);
TexImage3D(target, level, internalFormat, width, height, depth, border,
- unpackFormat, unpackType, srcView, 0);
+ unpackFormat, unpackType, src);
}
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, ErrorResult&)
+ GLenum unpackType, const dom::ArrayBufferView& view,
+ GLuint viewElemOffset, ErrorResult&)
{
+ const TexImageSourceAdapter src(view, viewElemOffset);
TexImage3D(target, level, internalFormat, width, height, depth, border,
- unpackFormat, unpackType, &srcView, srcElemOffset);
+ unpackFormat, unpackType, src);
}
- ////
+protected:
+ void TexImage3D(GLenum target, GLint level, GLenum internalFormat, GLsizei width,
+ GLsizei height, GLsizei depth, GLint border, GLenum unpackFormat,
+ GLenum unpackType, const TexImageSource& src)
+ {
+ const char funcName[] = "texImage3D";
+ const uint8_t funcDims = 3;
+ TexImage(funcName, funcDims, target, level, internalFormat, width, height, depth,
+ border, unpackFormat, unpackType, src);
+ }
+
+ ////////////////////////////////////
+
+public:
+ template<typename T>
+ void TexSubImage3D(GLenum target, GLint level, GLint xOffset, GLint yOffset,
+ GLint zOffset, GLsizei width, GLsizei height, GLsizei depth,
+ GLenum unpackFormat, GLenum unpackType, const T& anySrc,
+ ErrorResult& out_error)
+ {
+ const TexImageSourceAdapter src(anySrc, &out_error);
+ TexSubImage3D(target, level, xOffset, yOffset, zOffset, width, height, depth,
+ unpackFormat, unpackType, src);
+ }
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& 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);
-
- ////
+ ErrorResult&)
+ {
+ const TexImageSourceAdapter src(srcView, srcElemOffset);
+ TexSubImage3D(target, level, xOffset, yOffset, zOffset, width, height, depth,
+ unpackFormat, unpackType, src);
+ }
- void CompressedTexImage3D(GLenum target, GLint level, GLenum internalFormat,
- 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& srcView,
- GLuint srcElemOffset);
-
- ////////////////
- // Texture PBOs
-
- void TexImage3D(GLenum target, GLint level, GLenum internalFormat, GLsizei width,
- GLsizei height, GLsizei depth, GLint border, GLenum unpackFormat,
- GLenum unpackType, WebGLsizeiptr offset, ErrorResult&);
-
+protected:
void TexSubImage3D(GLenum target, GLint level, GLint xOffset, GLint yOffset,
GLint zOffset, GLsizei width, GLsizei height, GLsizei depth,
- GLenum unpackFormat, GLenum unpackType, WebGLsizeiptr offset,
- ErrorResult&);
+ GLenum unpackFormat, GLenum unpackType, const TexImageSource& src)
+ {
+ const char funcName[] = "texSubImage3D";
+ const uint8_t funcDims = 3;
+ TexSubImage(funcName, funcDims, target, level, xOffset, yOffset, zOffset, width,
+ height, depth, unpackFormat, unpackType, src);
+ }
+public:
// -------------------------------------------------------------------------
// Programs and shaders - WebGL2ContextPrograms.cpp
GLint GetFragDataLocation(WebGLProgram* program, const nsAString& name);
// -------------------------------------------------------------------------
// Uniforms and attributes - WebGL2ContextUniforms.cpp
void VertexAttribIPointer(GLuint index, GLint size, GLenum type, GLsizei stride, GLintptr offset);
--- a/dom/canvas/WebGL2ContextTextures.cpp
+++ b/dom/canvas/WebGL2ContextTextures.cpp
@@ -6,318 +6,28 @@
#include "GLContext.h"
#include "WebGL2Context.h"
#include "WebGLContextUtils.h"
#include "WebGLTexture.h"
namespace mozilla {
void
-WebGL2Context::TexStorage2D(GLenum rawTexTarget, GLsizei levels, GLenum internalFormat,
- GLsizei width, GLsizei height)
+WebGL2Context::TexStorage(const char* funcName, uint8_t funcDims, GLenum rawTarget,
+ GLsizei levels, GLenum internalFormat, GLsizei width,
+ GLsizei height, GLsizei depth)
{
- const char funcName[] = "TexStorage2D";
- const uint8_t funcDims = 2;
-
TexTarget target;
WebGLTexture* tex;
- if (!ValidateTexTarget(this, funcName, funcDims, rawTexTarget, &target, &tex))
- return;
-
- const GLsizei depth = 1;
- tex->TexStorage(funcName, target, levels, internalFormat, width, height, depth);
-}
-
-void
-WebGL2Context::TexStorage3D(GLenum rawTexTarget, GLsizei levels, GLenum internalFormat,
- GLsizei width, GLsizei height, GLsizei depth)
-{
- const char funcName[] = "texStorage3D";
- const uint8_t funcDims = 3;
-
- TexTarget target;
- WebGLTexture* tex;
- if (!ValidateTexTarget(this, funcName, funcDims, rawTexTarget, &target, &tex))
+ if (!ValidateTexTarget(this, funcName, funcDims, rawTarget, &target, &tex))
return;
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::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 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, srcView, 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& 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))
- {
- 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, &srcView, srcElemOffset);
-}
-
-void
-WebGL2Context::TexSubImage3D(GLenum rawTexImageTarget, GLint level, GLint xOffset,
- GLint yOffset, GLint zOffset, GLenum unpackFormat,
- 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))
- {
- return;
- }
-
- const bool isSubImage = true;
- 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, 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);
-}
-
-void
-WebGL2Context::CompressedTexImage3D(GLenum rawTexImageTarget, GLint level,
- GLenum internalFormat, GLsizei width, GLsizei height,
- GLsizei depth, GLint border,
- 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, srcView, 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& 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, srcView, 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";
- const uint8_t funcDims = 3;
-
- TexImageTarget target;
- WebGLTexture* tex;
- if (!ValidateTexImageTarget(this, funcName, funcDims, rawTexImageTarget, &target,
- &tex))
- {
- return;
- }
-
- tex->CopyTexSubImage(funcName, target, level, xOffset, yOffset, zOffset, x, y, width,
- height);
-}
-
-////////////////////
-
-void
-WebGLContext::TexImage2D(GLenum rawTexImageTarget, GLint level, GLenum internalFormat,
- GLsizei width, GLsizei height, GLint border,
- GLenum unpackFormat, GLenum unpackType, WebGLsizeiptr offset,
- ErrorResult&)
-{
- const char funcName[] = "texImage2D";
- const uint8_t funcDims = 2;
-
- TexImageTarget target;
- WebGLTexture* tex;
- if (!ValidateTexImageTarget(this, funcName, funcDims, rawTexImageTarget, &target,
- &tex))
- {
- return;
- }
-
- 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, offset);
-}
-
-void
-WebGLContext::TexSubImage2D(GLenum rawTexImageTarget, GLint level, GLint xOffset,
- GLint yOffset, GLsizei width, GLsizei height,
- GLenum unpackFormat, GLenum unpackType, WebGLsizeiptr offset,
- ErrorResult&)
-{
- 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;
- const GLsizei depth = 1;
- const GLint border = 0;
- tex->TexOrSubImage(isSubImage, funcName, target, level, internalFormat, xOffset,
- yOffset, zOffset, width, height, depth, border, unpackFormat,
- unpackType, offset);
-}
-
-//////////
-
-void
-WebGL2Context::TexImage3D(GLenum rawTexImageTarget, GLint level, GLenum internalFormat,
- GLsizei width, GLsizei height, GLsizei depth, GLint border,
- GLenum unpackFormat, GLenum unpackType, WebGLsizeiptr offset,
- ErrorResult&)
-{
- const char funcName[] = "texImage3D";
- const uint8_t funcDims = 3;
-
- TexImageTarget target;
- WebGLTexture* tex;
- if (!ValidateTexImageTarget(this, funcName, funcDims, rawTexImageTarget, &target,
- &tex))
- {
- 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, width, height, depth, border, unpackFormat,
- unpackType, offset);
-}
-
-void
-WebGL2Context::TexSubImage3D(GLenum rawTexImageTarget, GLint level, GLint xOffset,
- GLint yOffset, GLint zOffset, GLsizei width, GLsizei height,
- GLsizei depth, GLenum unpackFormat, GLenum unpackType,
- WebGLsizeiptr offset, ErrorResult&)
-{
- 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;
- const GLint border = 0;
- tex->TexOrSubImage(isSubImage, funcName, target, level, internalFormat, xOffset,
- yOffset, zOffset, width, height, depth, border, unpackFormat,
- unpackType, offset);
-}
-
////////////////////
/*virtual*/ bool
WebGL2Context::IsTexParamValid(GLenum pname) const
{
switch (pname) {
case LOCAL_GL_TEXTURE_BASE_LEVEL:
case LOCAL_GL_TEXTURE_COMPARE_FUNC:
--- a/dom/canvas/WebGLContext.h
+++ b/dom/canvas/WebGLContext.h
@@ -190,16 +190,72 @@ struct IndexedBufferBinding
uint64_t mRangeStart;
uint64_t mRangeSize;
IndexedBufferBinding();
uint64_t ByteCount() const;
};
+////////////////////////////////////
+
+struct TexImageSource
+{
+ const dom::ArrayBufferView* mView;
+ GLuint mViewElemOffset;
+
+ const WebGLsizeiptr* mPboOffset;
+
+ const dom::ImageData* mImageData;
+
+ const dom::Element* mDomElem;
+ ErrorResult* mOut_error;
+
+protected:
+ TexImageSource() {
+ memset(this, 0, sizeof(*this));
+ }
+};
+
+////
+
+struct TexImageSourceAdapter final : public TexImageSource
+{
+ TexImageSourceAdapter(const dom::Nullable<dom::ArrayBufferView>& maybeView,
+ ErrorResult*)
+ {
+ if (!maybeView.IsNull()) {
+ mView = &(maybeView.Value());
+ }
+ }
+
+ TexImageSourceAdapter(const dom::ArrayBufferView& view, ErrorResult*) {
+ mView = &view;
+ }
+
+ TexImageSourceAdapter(const dom::ArrayBufferView& view, GLuint viewElemOffset) {
+ mView = &view;
+ mViewElemOffset = viewElemOffset;
+ }
+
+ template<typename ignoredT>
+ TexImageSourceAdapter(WebGLsizeiptr pboOffset, ignoredT) {
+ mPboOffset = &pboOffset;
+ }
+
+ TexImageSourceAdapter(const dom::ImageData& imageData, ErrorResult*) {
+ mImageData = &imageData;
+ }
+
+ TexImageSourceAdapter(const dom::Element& domElem, ErrorResult* const out_error) {
+ mDomElem = &domElem;
+ mOut_error = out_error;
+ }
+};
+
////////////////////////////////////////////////////////////////////////////////
class WebGLContext
: public nsIDOMWebGLRenderingContext
, public nsICanvasRenderingContextInternal
, public nsSupportsWeakReference
, public WebGLContextUnchecked
, public WebGLRectangleObject
@@ -933,170 +989,224 @@ public:
protected:
JS::Value GetTexParameter(GLenum texTarget, GLenum pname);
void TexParameter_base(GLenum texTarget, GLenum pname, GLint* maybeIntParam,
GLfloat* maybeFloatParam);
virtual bool IsTexParamValid(GLenum pname) const;
- // Upload funcs
-public:
- void CompressedTexImage2D(GLenum texImageTarget, GLint level, GLenum internalFormat,
- GLsizei width, GLsizei height, GLint border,
- const dom::ArrayBufferView& view, GLuint srcElemOffset = 0);
- void CompressedTexSubImage2D(GLenum texImageTarget, GLint level, GLint xOffset,
- GLint yOffset, GLsizei width, GLsizei height,
- GLenum unpackFormat, const dom::ArrayBufferView& view,
- GLuint srcElemOffset = 0);
-
- 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&)
+public:
+ template<typename T>
+ void CompressedTexImage2D(GLenum target, GLint level, GLenum internalFormat,
+ GLsizei width, GLsizei height, GLint border,
+ const T& anySrc, GLuint viewElemOffset = 0)
{
- const dom::ArrayBufferView* view = nullptr;
- if (!maybeView.IsNull()) {
- view = &(maybeView.Value());
- }
-
- TexImage2D(texImageTarget, level, internalFormat, width, height, border,
- unpackFormat, unpackType, view, 0);
+ const char funcName[] = "compressedTexImage2D";
+ const uint8_t funcDims = 2;
+ const GLsizei depth = 1;
+ const TexImageSourceAdapter src(anySrc, viewElemOffset);
+ CompressedTexImage(funcName, funcDims, target, level, internalFormat, width,
+ height, depth, border, src);
}
- void TexImage2D(GLenum texImageTarget, GLint level, GLenum internalFormat,
- GLsizei width, GLsizei height, GLint border, GLenum unpackFormat,
- GLenum unpackType, const dom::ArrayBufferView& srcView,
- GLuint srcElemOffset, ErrorResult&)
+ 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)
{
- TexImage2D(texImageTarget, level, internalFormat, width, height, border,
- unpackFormat, unpackType, &srcView, srcElemOffset);
+ const char funcName[] = "compressedTexSubImage2D";
+ const uint8_t funcDims = 2;
+ const GLint zOffset = 0;
+ const GLsizei depth = 1;
+ const TexImageSourceAdapter src(anySrc, viewElemOffset);
+ CompressedTexSubImage(funcName, funcDims, target, level, xOffset, yOffset,
+ zOffset, width, height, depth, unpackFormat, src);
}
protected:
- void TexImage2D(GLenum texImageTarget, GLint level, GLenum internalFormat,
- GLsizei width, GLsizei height, GLint border, GLenum unpackFormat,
- GLenum unpackType, const dom::ArrayBufferView* srcView,
- GLuint srcElemOffset);
+ 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);
+
+ 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);
+
+ ////////////////////////////////////
public:
- void TexImage2D(GLenum texImageTarget, GLint level, GLenum internalFormat,
- GLenum unpackFormat, GLenum unpackType,
- const dom::ImageData& imageData, ErrorResult& out_error);
- void TexImage2D(GLenum texImageTarget, GLint level, GLenum internalFormat,
- GLenum unpackFormat, GLenum unpackType, const dom::Element& elem,
- ErrorResult& out_error);
- void TexImage2D(GLenum texImageTarget, GLint level, GLenum internalFormat,
- GLsizei width, GLsizei height, GLint border, GLenum unpackFormat,
- GLenum unpackType, WebGLsizeiptr offset, ErrorResult&);
+ 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,
+ GLsizei height)
+ {
+ const char funcName[] = "copyTexSubImage2D";
+ const uint8_t funcDims = 2;
+ const GLint zOffset = 0;
+ CopyTexSubImage(funcName, funcDims, target, level, xOffset, yOffset, zOffset,
+ x, y, width, height);
+ }
+
+protected:
+ void CopyTexSubImage(const char* funcName, uint8_t funcDims, GLenum target,
+ GLint level, GLint xOffset, GLint yOffset, GLint zOffset,
+ GLint x, GLint y, GLsizei width, GLsizei height);
+
+ ////////////////////////////////////
+ // TexImage
+
+ // Implicit width/height uploads
+
+public:
+ template<typename T>
+ void TexImage2D(GLenum target, GLint level, GLenum internalFormat,
+ GLenum unpackFormat, GLenum unpackType, const T& src,
+ ErrorResult& out_error)
+ {
+ GLsizei width = 0;
+ GLsizei height = 0;
+ GLint border = 0;
+ TexImage2D(target, level, internalFormat, width, height, border, unpackFormat,
+ unpackType, src, out_error);
+ }
+
+ template<typename T>
+ void TexSubImage2D(GLenum target, GLint level, GLint xOffset, GLint yOffset,
+ GLenum unpackFormat, GLenum unpackType, const T& src,
+ ErrorResult& out_error)
+ {
+ GLsizei width = 0;
+ GLsizei height = 0;
+ TexSubImage2D(target, level, xOffset, yOffset, width, height, unpackFormat,
+ unpackType, src, out_error);
+ }
////
- void TexSubImage2D(GLenum texImageTarget, GLint level, GLint xOffset, GLint yOffset,
- GLenum unpackFormat, GLenum unpackType,
- const dom::ImageData& imageData, ErrorResult& out_error);
- void TexSubImage2D(GLenum texImageTarget, GLint level, GLint xOffset, GLint yOffset,
- GLenum unpackFormat, GLenum unpackType, const dom::Element& elem,
- ErrorResult& out_error);
+ template<typename T>
+ void TexImage2D(GLenum target, GLint level, GLenum internalFormat, GLsizei width,
+ GLsizei height, GLint border, GLenum unpackFormat, GLenum unpackType,
+ const T& anySrc, ErrorResult& out_error)
+ {
+ const TexImageSourceAdapter src(anySrc, &out_error);
+ TexImage2D(target, level, internalFormat, width, height, border, unpackFormat,
+ unpackType, src);
+ }
- void TexSubImage2D(GLenum texImageTarget, GLint level, GLint xOffset, GLint yOffset,
- GLsizei width, GLsizei height, GLenum unpackFormat,
- GLenum unpackType, WebGLsizeiptr offset, ErrorResult&);
+ void TexImage2D(GLenum target, GLint level, GLenum internalFormat, GLsizei width,
+ GLsizei height, GLint border, GLenum unpackFormat, GLenum unpackType,
+ const dom::ArrayBufferView& view, GLuint viewElemOffset,
+ ErrorResult&)
+ {
+ const TexImageSourceAdapter src(view, viewElemOffset);
+ TexImage2D(target, level, internalFormat, width, height, border, unpackFormat,
+ unpackType, src);
+ }
- ////////////////
- // dom::ImageData
-
- void TexImage2D(GLenum texImageTarget, GLint level, GLenum internalFormat,
- GLenum unpackFormat, GLenum unpackType,
- const dom::ImageData* imageData, ErrorResult& out_error)
+protected:
+ void TexImage2D(GLenum target, GLint level, GLenum internalFormat, GLsizei width,
+ GLsizei height, GLint border, GLenum unpackFormat,
+ GLenum unpackType, const TexImageSource& src)
{
const char funcName[] = "texImage2D";
- if (IsContextLost())
- return;
-
- if (!imageData)
- return ErrorInvalidValue("%s: `data` must not be null.", funcName);
-
- TexImage2D(texImageTarget, level, internalFormat, unpackFormat, unpackType,
- *imageData, out_error);
+ const uint8_t funcDims = 2;
+ const GLsizei depth = 1;
+ TexImage(funcName, funcDims, target, level, internalFormat, width, height, depth,
+ border, unpackFormat, unpackType, src);
}
- void TexSubImage2D(GLenum texImageTarget, GLint level, GLint xOffset, GLint yOffset,
- GLenum unpackFormat, GLenum unpackType,
- const dom::ImageData* imageData, ErrorResult& out_error)
+ void TexImage(const char* funcName, uint8_t funcDims, GLenum target, GLint level,
+ GLenum internalFormat, GLsizei width, GLsizei height, GLsizei depth,
+ GLint border, GLenum unpackFormat, GLenum unpackType,
+ const TexImageSource& src);
+
+ ////
+
+public:
+ template<typename T>
+ void TexSubImage2D(GLenum target, GLint level, GLint xOffset, GLint yOffset,
+ GLsizei width, GLsizei height, GLenum unpackFormat,
+ GLenum unpackType, const T& anySrc, ErrorResult& out_error)
+ {
+ const TexImageSourceAdapter src(anySrc, &out_error);
+ TexSubImage2D(target, level, xOffset, yOffset, width, height, unpackFormat,
+ unpackType, src);
+ }
+
+ void TexSubImage2D(GLenum target, GLint level, GLint xOffset, GLint yOffset,
+ GLsizei width, GLsizei height, GLenum unpackFormat,
+ GLenum unpackType, const dom::ArrayBufferView& view,
+ GLuint viewElemOffset, ErrorResult&)
+ {
+ const TexImageSourceAdapter src(view, viewElemOffset);
+ TexSubImage2D(target, level, xOffset, yOffset, width, height, unpackFormat,
+ unpackType, src);
+ }
+
+protected:
+ void TexSubImage2D(GLenum target, GLint level, GLint xOffset, GLint yOffset,
+ GLsizei width, GLsizei height, GLenum unpackFormat,
+ GLenum unpackType, const TexImageSource& src)
{
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);
+ const uint8_t funcDims = 2;
+ const GLint zOffset = 0;
+ const GLsizei depth = 1;
+ TexSubImage(funcName, funcDims, target, level, xOffset, yOffset, zOffset, width,
+ height, depth, unpackFormat, unpackType, src);
}
- ////
- // 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;
+ void TexSubImage(const char* funcName, uint8_t funcDims, GLenum target, GLint level,
+ GLint xOffset, GLint yOffset, GLint zOffset, GLsizei width,
+ GLsizei height, GLsizei depth, GLenum unpackFormat,
+ GLenum unpackType, const TexImageSource& src);
- if (maybeSrc.IsNull())
- return ErrorInvalidValue("%s: `data` must not be null.", funcName);
-
- TexSubImage2D(texImageTarget, level, xOffset, yOffset, width, height,
- unpackFormat, unpackType, maybeSrc.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);
+ UniquePtr<webgl::TexUnpackBlob>
+ From(const char* funcName, TexImageTarget target, GLsizei rawWidth, GLsizei rawHeight,
+ GLsizei rawDepth, GLint border, const TexImageSource& src,
+ dom::Uint8ClampedArray* const scopedArr);
protected:
bool ValidateTexImageSpecification(const char* funcName, uint8_t funcDims,
GLenum texImageTarget, GLint level,
GLsizei width, GLsizei height, GLsizei depth,
GLint border,
TexImageTarget* const out_target,
WebGLTexture** const out_texture,
WebGLTexture::ImageInfo** const out_imageInfo);
bool ValidateTexImageSelection(const char* funcName, uint8_t funcDims,
GLenum texImageTarget, GLint level, GLint xOffset,
GLint yOffset, GLint zOffset, GLsizei width,
GLsizei height, GLsizei depth,
TexImageTarget* const out_target,
WebGLTexture** const out_texture,
WebGLTexture::ImageInfo** const out_imageInfo);
-
bool ValidateUnpackInfo(const char* funcName, bool usePBOs, GLenum format,
GLenum type, webgl::PackingInfo* const out);
+ 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);
+
// -----------------------------------------------------------------------------
// Vertices Feature (WebGLContextVertices.cpp)
GLenum mPrimRestartTypeBytes;
public:
void DrawArrays(GLenum mode, GLint first, GLsizei count);
void DrawArraysInstanced(GLenum mode, GLint first, GLsizei count,
GLsizei primcount);
@@ -1463,20 +1573,22 @@ protected:
bool ValidateNonNegative(const char* funcName, const char* argName, int64_t val) {
if (MOZ_UNLIKELY(val < 0)) {
ErrorInvalidValue("%s: `%s` must be non-negative.", funcName, argName);
return false;
}
return true;
}
+public:
bool ValidateArrayBufferView(const char* funcName, const dom::ArrayBufferView& view,
GLuint elemOffset, GLuint elemCountOverride,
uint8_t** const out_bytes, size_t* const out_byteLen);
+protected:
////
void Invalidate();
void DestroyResourcesAndContext();
void MakeContextCurrent() const;
// helpers
--- a/dom/canvas/WebGLContextTextures.cpp
+++ b/dom/canvas/WebGLContextTextures.cpp
@@ -312,261 +312,109 @@ WebGLContext::TexParameter_base(GLenum r
WebGLTexture* tex;
if (!ValidateTexTarget(this, funcName, funcDims, rawTexTarget, &texTarget, &tex))
return;
tex->TexParameter(texTarget, pname, maybeIntParam, maybeFloatParam);
}
//////////////////////////////////////////////////////////////////////////////////////////
-//////////////////////////////////////////////////////////////////////////////////////////
// Uploads
-
-////////////////////
-// TexImage
-
void
-WebGLContext::TexImage2D(GLenum rawTexImageTarget, GLint level, GLenum internalFormat,
- GLsizei width, GLsizei height, GLint border, GLenum unpackFormat,
- GLenum unpackType, const dom::ArrayBufferView* maybeView,
- GLuint elemOffset)
+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 char funcName[] = "texImage2D";
- const uint8_t funcDims = 2;
-
TexImageTarget target;
WebGLTexture* tex;
- if (!ValidateTexImageTarget(this, funcName, funcDims, rawTexImageTarget, &target,
- &tex))
- {
+ if (!ValidateTexImageTarget(this, funcName, funcDims, rawTarget, &target, &tex))
return;
- }
-
- 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, elemOffset);
-}
-void
-WebGLContext::TexImage2D(GLenum rawTexImageTarget, GLint level, GLenum internalFormat,
- GLenum unpackFormat, GLenum unpackType,
- 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))
- {
- 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, imageData);
+ tex->CompressedTexImage(funcName, target, level, internalFormat, width, height, depth,
+ border, src);
}
void
-WebGLContext::TexImage2D(GLenum rawTexImageTarget, GLint level, GLenum internalFormat,
- GLenum unpackFormat, GLenum unpackType, const dom::Element& elem,
- ErrorResult& out_error)
+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 char funcName[] = "texImage2D";
- const uint8_t funcDims = 2;
-
- TexImageTarget target;
- WebGLTexture* tex;
- if (!ValidateTexImageTarget(this, funcName, funcDims, rawTexImageTarget, &target,
- &tex))
- {
- 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);
-}
-
-////////////////////////////////////////
-// TexSubImage
-
-void
-WebGLContext::TexSubImage2D(GLenum rawTexImageTarget, GLint level, GLint xOffset,
- GLint yOffset, GLsizei width, GLsizei height,
- GLenum unpackFormat, GLenum unpackType,
- const dom::ArrayBufferView& view, GLuint elemOffset,
- ErrorResult&)
-{
- const char funcName[] = "texSubImage2D";
- const uint8_t funcDims = 2;
-
TexImageTarget target;
WebGLTexture* tex;
- if (!ValidateTexImageTarget(this, funcName, funcDims, rawTexImageTarget, &target,
- &tex))
- {
+ if (!ValidateTexImageTarget(this, funcName, funcDims, rawTarget, &target, &tex))
return;
- }
-
- 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, &view, elemOffset);
-}
-void
-WebGLContext::TexSubImage2D(GLenum rawTexImageTarget, GLint level, GLint xOffset,
- GLint yOffset, GLenum unpackFormat, GLenum unpackType,
- 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))
- {
- 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, imageData);
+ tex->CompressedTexSubImage(funcName, target, level, xOffset, yOffset, zOffset, width,
+ height, depth, unpackFormat, src);
}
-void
-WebGLContext::TexSubImage2D(GLenum rawTexImageTarget, GLint level, GLint xOffset,
- GLint yOffset, GLenum unpackFormat, GLenum unpackType,
- 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);
-}
-
-////////////////////////////////////////
-// CompressedTex(Sub)Image
+////
void
-WebGLContext::CompressedTexImage2D(GLenum rawTexImageTarget, GLint level,
- GLenum internalFormat, GLsizei width, GLsizei height,
- GLint border, const dom::ArrayBufferView& srcView,
- GLuint srcElemOffset)
-{
- const char funcName[] = "compressedTexImage2D";
- const uint8_t funcDims = 2;
-
- TexImageTarget target;
- WebGLTexture* tex;
- if (!ValidateTexImageTarget(this, funcName, funcDims, rawTexImageTarget, &target,
- &tex))
- {
- return;
- }
-
- const GLsizei depth = 1;
- tex->CompressedTexImage(funcName, target, level, internalFormat, width, height, depth,
- border, srcView, srcElemOffset);
-}
-
-void
-WebGLContext::CompressedTexSubImage2D(GLenum rawTexImageTarget, GLint level,
- GLint xOffset, GLint yOffset, GLsizei width,
- GLsizei height, GLenum sizedUnpackFormat,
- const dom::ArrayBufferView& srcView,
- GLuint srcElemOffset)
-{
- const char funcName[] = "compressedTexSubImage2D";
- const uint8_t funcDims = 2;
-
- TexImageTarget target;
- WebGLTexture* tex;
- if (!ValidateTexImageTarget(this, funcName, funcDims, rawTexImageTarget, &target,
- &tex))
- {
- return;
- }
-
- const GLint zOffset = 0;
- const GLsizei depth = 1;
- tex->CompressedTexSubImage(funcName, target, level, xOffset, yOffset, zOffset, width,
- height, depth, sizedUnpackFormat, srcView, srcElemOffset);
-}
-
-////////////////////////////////////////
-// CopyTex(Sub)Image
-
-void
-WebGLContext::CopyTexImage2D(GLenum rawTexImageTarget, GLint level, GLenum internalFormat,
+WebGLContext::CopyTexImage2D(GLenum rawTarget, GLint level, GLenum internalFormat,
GLint x, GLint y, GLsizei width, GLsizei height,
GLint border)
{
const char funcName[] = "copyTexImage2D";
const uint8_t funcDims = 2;
TexImageTarget target;
WebGLTexture* tex;
- if (!ValidateTexImageTarget(this, funcName, funcDims, rawTexImageTarget, &target,
- &tex))
- {
+ if (!ValidateTexImageTarget(this, funcName, funcDims, rawTarget, &target, &tex))
return;
- }
tex->CopyTexImage2D(target, level, internalFormat, x, y, width, height, border);
}
void
-WebGLContext::CopyTexSubImage2D(GLenum rawTexImageTarget, GLint level, GLint xOffset,
- GLint yOffset, GLint x, GLint y, GLsizei width,
- GLsizei height)
+WebGLContext::CopyTexSubImage(const char* funcName, uint8_t funcDims, GLenum rawTarget,
+ GLint level, GLint xOffset, GLint yOffset, GLint zOffset,
+ GLint x, GLint y, GLsizei width, GLsizei height)
{
- const char funcName[] = "copyTexSubImage2D";
- const uint8_t funcDims = 2;
-
TexImageTarget target;
WebGLTexture* tex;
- if (!ValidateTexImageTarget(this, funcName, funcDims, rawTexImageTarget, &target,
- &tex))
- {
+ if (!ValidateTexImageTarget(this, funcName, funcDims, rawTarget, &target, &tex))
return;
- }
-
- const GLint zOffset = 0;
tex->CopyTexSubImage(funcName, target, level, xOffset, yOffset, zOffset, x, y, width,
height);
}
+////
+
+void
+WebGLContext::TexImage(const char* funcName, uint8_t funcDims, GLenum rawTarget,
+ GLint level, GLenum internalFormat, GLsizei width, GLsizei height,
+ GLsizei depth, GLint border, GLenum unpackFormat,
+ GLenum unpackType, const TexImageSource& src)
+{
+ TexImageTarget target;
+ WebGLTexture* tex;
+ if (!ValidateTexImageTarget(this, funcName, funcDims, rawTarget, &target, &tex))
+ return;
+
+ const webgl::PackingInfo pi = {unpackFormat, unpackType};
+ tex->TexImage(funcName, target, level, internalFormat, width, height, depth, border,
+ pi, src);
+}
+
+void
+WebGLContext::TexSubImage(const char* funcName, uint8_t funcDims, GLenum rawTarget,
+ GLint level, GLint xOffset, GLint yOffset, GLint zOffset,
+ GLsizei width, GLsizei height, GLsizei depth,
+ GLenum unpackFormat, GLenum unpackType,
+ const TexImageSource& src)
+{
+ TexImageTarget target;
+ WebGLTexture* tex;
+ if (!ValidateTexImageTarget(this, funcName, funcDims, rawTarget, &target, &tex))
+ return;
+
+ const webgl::PackingInfo pi = {unpackFormat, unpackType};
+ tex->TexSubImage(funcName, target, level, xOffset, yOffset, zOffset, width, height,
+ depth, pi, src);
+}
+
} // namespace mozilla
--- a/dom/canvas/WebGLTexture.h
+++ b/dom/canvas/WebGLTexture.h
@@ -20,16 +20,17 @@
#include "WebGLFramebufferAttachable.h"
#include "WebGLObjectModel.h"
#include "WebGLStrongTypes.h"
#include "WebGLTypes.h"
namespace mozilla {
class ErrorResult;
class WebGLContext;
+struct TexImageSource;
namespace dom {
class Element;
class HTMLVideoElement;
class ImageData;
class ArrayBufferViewOrSharedArrayBufferView;
} // namespace dom
@@ -227,38 +228,16 @@ public:
JS::Value GetTexParameter(TexTarget texTarget, GLenum pname);
bool IsTexture() const;
void TexParameter(TexTarget texTarget, GLenum pname, GLint* maybeIntParam,
GLfloat* maybeFloatParam);
////////////////////////////////////
// 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* 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,
- GLint zOffset, GLenum unpackFormat, GLenum unpackType,
- 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:
void TexOrSubImageBlob(bool isSubImage, const char* funcName, TexImageTarget target,
GLint level, GLenum internalFormat, GLint xOffset,
GLint yOffset, GLint zOffset,
const webgl::PackingInfo& pi,
const webgl::TexUnpackBlob* blob);
bool ValidateTexImageSpecification(const char* funcName, TexImageTarget target,
@@ -272,32 +251,39 @@ protected:
WebGLTexture::ImageInfo** const out_imageInfo);
bool ValidateCopyTexImageForFeedback(const char* funcName, uint32_t level) const;
bool ValidateUnpack(const char* funcName, const webgl::TexUnpackBlob* blob,
bool isFunc3D, const webgl::PackingInfo& srcPI) const;
public:
void TexStorage(const char* funcName, TexTarget target, GLsizei levels,
GLenum sizedFormat, GLsizei width, GLsizei height, GLsizei depth);
+ void TexImage(const char* funcName, TexImageTarget target, GLint level,
+ GLenum internalFormat, GLsizei width, GLsizei height, GLsizei depth,
+ GLint border, const webgl::PackingInfo& pi, const TexImageSource& src);
+ void TexSubImage(const char* funcName, TexImageTarget target, GLint level,
+ GLint xOffset, GLint yOffset, GLint zOffset, GLsizei width,
+ GLsizei height, GLsizei depth, const webgl::PackingInfo& pi,
+ const TexImageSource& src);
protected:
void TexImage(const char* funcName, TexImageTarget target, GLint level,
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 dom::ArrayBufferView& srcView, GLuint srcElemOffset);
+ GLsizei depth, GLint border, const TexImageSource& src);
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& srcView, GLuint srcElemOffset);
+ const TexImageSource& src);
+
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
@@ -122,235 +122,95 @@ DoesJSTypeMatchUnpackType(GLenum unpackT
case LOCAL_GL_FLOAT:
return jsType == js::Scalar::Type::Float32;
default:
return false;
}
}
-bool
-WebGLContext::ValidateUnpackPixels(const char* funcName, uint32_t fullRows,
- uint32_t tailPixels, webgl::TexUnpackBlob* blob)
+static bool
+ValidateViewType(WebGLContext* webgl, const char* funcName, GLenum unpackType,
+ const TexImageSource& src)
{
- auto skipPixels = CheckedUint32(blob->mSkipPixels);
- skipPixels += CheckedUint32(blob->mSkipRows);
-
- const auto usedPixelsPerRow = CheckedUint32(blob->mSkipPixels) + blob->mWidth;
- if (!usedPixelsPerRow.isValid() || usedPixelsPerRow.value() > blob->mRowLength) {
- ErrorInvalidOperation("%s: UNPACK_SKIP_PIXELS + height > UNPACK_ROW_LENGTH.",
- funcName);
- return false;
- }
+ if (!src.mView)
+ return true;
+ const auto& view = *(src.mView);
- if (blob->mHeight > blob->mImageHeight) {
- ErrorInvalidOperation("%s: height > UNPACK_IMAGE_HEIGHT.", funcName);
- return false;
- }
-
- //////
-
- // The spec doesn't bound SKIP_ROWS + height <= IMAGE_HEIGHT, unfortunately.
- auto skipFullRows = CheckedUint32(blob->mSkipImages) * blob->mImageHeight;
- skipFullRows += blob->mSkipRows;
-
- MOZ_ASSERT(blob->mDepth >= 1);
- MOZ_ASSERT(blob->mHeight >= 1);
- auto usedFullRows = CheckedUint32(blob->mDepth - 1) * blob->mImageHeight;
- usedFullRows += blob->mHeight - 1; // Full rows in the final image, excluding the tail.
-
- const auto fullRowsNeeded = skipFullRows + usedFullRows;
- if (!fullRowsNeeded.isValid()) {
- ErrorOutOfMemory("%s: Invalid calculation for required row count.",
- funcName);
+ const auto& jsType = view.Type();
+ if (!DoesJSTypeMatchUnpackType(unpackType, jsType)) {
+ webgl->ErrorInvalidOperation("%s: ArrayBufferView type not compatible with"
+ " `type`.",
+ funcName);
return false;
}
- if (fullRows > fullRowsNeeded.value())
- return true;
-
- if (fullRows == fullRowsNeeded.value() && tailPixels >= usedPixelsPerRow.value()) {
- blob->mNeedsExactUpload = true;
- return true;
- }
-
- ErrorInvalidOperation("%s: Desired upload requires more data than is available: (%u"
- " rows plus %u pixels needed, %u rows plus %u pixels"
- " available)",
- funcName, fullRowsNeeded.value(), usedPixelsPerRow.value(),
- fullRows, tailPixels);
- return false;
+ return true;
}
static bool
-ValidateUnpackBytes(WebGLContext* webgl, const char* funcName, uint32_t width,
- uint32_t height, uint32_t depth, const webgl::PackingInfo& pi,
- size_t byteCount, webgl::TexUnpackBlob* blob)
+ValidateUnpackInfo(WebGLContext* webgl, const char* funcName,
+ const webgl::PackingInfo& pi)
{
- 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);
-
- const auto fullRows = byteCount / rowStride;
- if (!fullRows.isValid()) {
- webgl->ErrorOutOfMemory("%s: Unacceptable upload size calculated.");
+ if (!webgl->mFormatUsage->AreUnpackEnumsValid(pi.format, pi.type)) {
+ webgl->ErrorInvalidEnum("%s: Invalid unpack format/type: 0x%04x/0x%04x", funcName,
+ pi.format, pi.type);
return false;
}
- const auto bodyBytes = fullRows.value() * rowStride.value();
- const auto tailPixels = (byteCount - bodyBytes) / bytesPerPixel;
-
- return webgl->ValidateUnpackPixels(funcName, fullRows.value(), tailPixels, blob);
-}
-
-bool
-WebGLContext::ValidateUnpackInfo(const char* funcName, bool usePBOs, GLenum format,
- GLenum type, webgl::PackingInfo* const out)
-{
- if (usePBOs != bool(mBoundPixelUnpackBuffer)) {
- ErrorInvalidOperation("%s: PACK_BUFFER must be %s.", funcName,
- (usePBOs ? "non-null" : "null"));
- return false;
- }
-
- if (mBoundPixelUnpackBuffer &&
- mBoundPixelUnpackBuffer->mNumActiveTFOs)
- {
- ErrorInvalidOperation("%s: Buffer is bound to an active transform feedback"
- " object.",
- funcName);
- return false;
- }
-
- if (!mFormatUsage->AreUnpackEnumsValid(format, type)) {
- ErrorInvalidEnum("%s: Invalid unpack format/type: 0x%04x/0x%04x", funcName,
- format, type);
- return false;
- }
-
- out->format = format;
- out->type = type;
return true;
}
-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* 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;
- size_t byteCount = 0;
+////////////////////////////////////////////////////////////////////////////////
- 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,
- const_cast<uint8_t**>(&bytes), &byteCount))
+static UniquePtr<webgl::TexUnpackBytes>
+FromView(WebGLContext* webgl, const char* funcName, TexImageTarget target,
+ uint32_t width, uint32_t height, uint32_t depth,
+ const dom::ArrayBufferView* view, GLuint viewElemOffset)
+{
+ const bool isClientData = true;
+ const uint8_t* bytes = nullptr;
+ size_t availByteCount = 0;
+ if (view) {
+ if (!webgl->ValidateArrayBufferView(funcName, *view, viewElemOffset, 0,
+ const_cast<uint8_t**>(&bytes),
+ &availByteCount))
{
- return;
+ return nullptr;
}
- } else if (isSubImage) {
- mContext->ErrorInvalidValue("%s: `pixels` must not be null.", funcName);
- return;
}
+ return MakeUnique<webgl::TexUnpackBytes>(webgl, target, width, height, depth,
+ isClientData, bytes, availByteCount);
+}
- const bool isClientData = true;
- webgl::TexUnpackBytes blob(mContext, target, width, height, depth, isClientData,
- bytes);
-
- if (bytes &&
- !ValidateUnpackBytes(mContext, funcName, width, height, depth, pi, byteCount,
- &blob))
- {
- return;
+static UniquePtr<webgl::TexUnpackBytes>
+FromPboOffset(WebGLContext* webgl, const char* funcName, TexImageTarget target,
+ uint32_t width, uint32_t height, uint32_t depth, WebGLsizeiptr pboOffset,
+ size_t availBufferBytes)
+{
+ if (pboOffset < 0) {
+ webgl->ErrorInvalidValue("%s: offset cannot be negative.", funcName);
+ return nullptr;
}
- TexOrSubImageBlob(isSubImage, funcName, target, level, internalFormat, xOffset,
- yOffset, zOffset, pi, &blob);
+ if (size_t(pboOffset) > availBufferBytes) {
+ webgl->ErrorInvalidOperation("%s: Offset is passed end of buffer.", funcName);
+ return nullptr;
+ }
+ availBufferBytes -= pboOffset;
+
+ const bool isClientData = false;
+ const auto ptr = (const uint8_t*)pboOffset;
+ return MakeUnique<webgl::TexUnpackBytes>(webgl, target, width, height, depth,
+ isClientData, ptr, availBufferBytes);
}
-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,
- WebGLsizeiptr offset)
-{
- uint32_t width, height, depth;
- if (!ValidateExtents(mContext, funcName, rawWidth, rawHeight, rawDepth, border,
- &width, &height, &depth))
- {
- return;
- }
-
- const bool usePBOs = true;
- webgl::PackingInfo pi;
- if (!mContext->ValidateUnpackInfo(funcName, usePBOs, unpackFormat, unpackType, &pi))
- return;
-
- ////
-
- if (offset < 0) {
- mContext->ErrorInvalidValue("%s: offset cannot be negative.", funcName);
- return;
- }
-
- const bool isClientData = false;
- const auto ptr = (const uint8_t*)offset;
- webgl::TexUnpackBytes blob(mContext, target, width, height, depth, isClientData, ptr);
-
- const auto& packBuffer = mContext->mBoundPixelUnpackBuffer;
- const auto bufferByteCount = packBuffer->ByteLength();
-
- uint32_t byteCount = 0;
- if (bufferByteCount >= uint64_t(offset)) {
- byteCount = bufferByteCount - offset;
- }
-
- if (!ValidateUnpackBytes(mContext, funcName, width, height, depth, pi, byteCount,
- &blob))
- {
- return;
- }
-
- TexOrSubImageBlob(isSubImage, funcName, target, level, internalFormat, xOffset,
- yOffset, zOffset, pi, &blob);
-}
-
-////////////////////////////////////////
-// ImageData
-
-static already_AddRefed<gfx::DataSourceSurface>
-FromImageData(WebGLContext* webgl, const char* funcName, GLenum unpackType,
+static UniquePtr<webgl::TexUnpackBlob>
+FromImageData(WebGLContext* webgl, const char* funcName, TexImageTarget target,
+ uint32_t width, uint32_t height, uint32_t depth,
const dom::ImageData& imageData, dom::Uint8ClampedArray* scopedArr)
{
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();
@@ -358,93 +218,56 @@ FromImageData(WebGLContext* webgl, const
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 =
- gfx::Factory::CreateWrappingDataSourceSurface(wrappableData,
- stride,
- size,
+ const RefPtr<gfx::DataSourceSurface> surf =
+ gfx::Factory::CreateWrappingDataSourceSurface(wrappableData, stride, size,
surfFormat);
if (!surf) {
webgl->ErrorOutOfMemory("%s: OOM in FromImageData.", funcName);
return nullptr;
}
- return surf.forget();
-}
+ ////
+
+ if (!width) {
+ width = imageData.Width();
+ }
-void
-WebGLTexture::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)
-{
- const bool usePBOs = false;
- webgl::PackingInfo pi;
- if (!mContext->ValidateUnpackInfo(funcName, usePBOs, unpackFormat, unpackType, &pi))
- return;
+ if (!height) {
+ height = imageData.Height();
+ }
- // Eventually, these will be args.
- 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;
+ ////
// 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 tailPixels = 0;
- if (!mContext->ValidateUnpackPixels(funcName, fullRows, tailPixels, &blob))
- return;
-
- TexOrSubImageBlob(isSubImage, funcName, target, level, internalFormat, xOffset,
- yOffset, zOffset, pi, &blob);
+ return MakeUnique<webgl::TexUnpackSurface>(webgl, target, width, height, depth, surf,
+ isAlphaPremult);
}
-////////////////////////////////////////
-// 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, const dom::Element& elem,
- ErrorResult* const out_error)
+UniquePtr<webgl::TexUnpackBlob>
+WebGLContext::FromDomElem(const char* funcName, TexImageTarget target, uint32_t width,
+ uint32_t height, uint32_t depth, const dom::Element& elem,
+ ErrorResult* const out_error)
{
- const bool usePBOs = false;
- webgl::PackingInfo pi;
- if (!mContext->ValidateUnpackInfo(funcName, usePBOs, unpackFormat, unpackType, &pi))
- return;
-
- //////
-
uint32_t flags = nsLayoutUtils::SFE_WANT_IMAGE_SURFACE |
nsLayoutUtils::SFE_USE_ELEMENT_SIZE_IF_VECTOR;
- if (mContext->mPixelStore_ColorspaceConversion == LOCAL_GL_NONE)
+ if (mPixelStore_ColorspaceConversion == LOCAL_GL_NONE)
flags |= nsLayoutUtils::SFE_NO_COLORSPACE_CONVERSION;
- if (!mContext->mPixelStore_PremultiplyAlpha)
+ if (!mPixelStore_PremultiplyAlpha)
flags |= nsLayoutUtils::SFE_PREFER_NO_PREMULTIPLY_ALPHA;
RefPtr<gfx::DrawTarget> idealDrawTarget = nullptr; // Don't care for now.
auto sfer = nsLayoutUtils::SurfaceFromElement(const_cast<dom::Element*>(&elem), flags,
idealDrawTarget);
//////
@@ -464,98 +287,175 @@ WebGLTexture::TexOrSubImage(bool isSubIm
elemHeight = surf->GetSize().height;
// WARNING: OSX can lose our MakeCurrent here.
dataSurf = surf->GetDataSurface();
}
//////
- // Eventually, these will be args.
- const uint32_t width = elemWidth;
- const uint32_t height = elemHeight;
- const uint32_t depth = 1;
+ if (!width) {
+ width = elemWidth;
+ }
+
+ if (!height) {
+ height = elemHeight;
+ }
+
+ ////
if (!layersImage && !dataSurf) {
const bool isClientData = true;
- const webgl::TexUnpackBytes blob(mContext, target, width, height, depth,
- isClientData, nullptr);
- TexOrSubImageBlob(isSubImage, funcName, target, level, internalFormat, xOffset,
- yOffset, zOffset, pi, &blob);
- return;
+ return MakeUnique<webgl::TexUnpackBytes>(this, target, width, height, depth,
+ isClientData, nullptr, 0);
}
//////
// While it's counter-intuitive, the shape of the SFEResult API means that we should
// try to pull out a surface first, and then, if we do pull out a surface, check
// CORS/write-only/etc..
if (!sfer.mCORSUsed) {
auto& srcPrincipal = sfer.mPrincipal;
- nsIPrincipal* dstPrincipal = mContext->GetCanvas()->NodePrincipal();
+ nsIPrincipal* dstPrincipal = GetCanvas()->NodePrincipal();
if (!dstPrincipal->Subsumes(srcPrincipal)) {
- mContext->GenerateWarning("%s: Cross-origin elements require CORS.",
- funcName);
+ GenerateWarning("%s: Cross-origin elements require CORS.", funcName);
out_error->Throw(NS_ERROR_DOM_SECURITY_ERR);
- return;
+ return nullptr;
}
}
if (sfer.mIsWriteOnly) {
// mIsWriteOnly defaults to true, and so will be true even if SFE merely
// failed. Thus we must test mIsWriteOnly after successfully retrieving an
// Image or SourceSurface.
- mContext->GenerateWarning("%s: Element is write-only, thus cannot be"
- " uploaded.",
- funcName);
+ GenerateWarning("%s: Element is write-only, thus cannot be uploaded.", funcName);
out_error->Throw(NS_ERROR_DOM_SECURITY_ERR);
- return;
+ return nullptr;
}
//////
// Ok, we're good!
- UniquePtr<webgl::TexUnpackBlob> blob;
const bool isAlphaPremult = sfer.mIsPremultiplied;
if (layersImage) {
- blob.reset(new webgl::TexUnpackImage(mContext, target, width, height, depth,
- layersImage, isAlphaPremult));
- } else {
- MOZ_ASSERT(dataSurf);
- blob.reset(new webgl::TexUnpackSurface(mContext, target, width, height, depth,
- dataSurf, isAlphaPremult));
+ return MakeUnique<webgl::TexUnpackImage>(this, target, width, height, depth,
+ layersImage, isAlphaPremult);
+ }
+
+ MOZ_ASSERT(dataSurf);
+ return MakeUnique<webgl::TexUnpackSurface>(this, target, width, height, depth,
+ dataSurf, isAlphaPremult);
+}
+
+////////////////////////////////////////
+
+UniquePtr<webgl::TexUnpackBlob>
+WebGLContext::From(const char* funcName, TexImageTarget target, GLsizei rawWidth,
+ GLsizei rawHeight, GLsizei rawDepth, GLint border,
+ const TexImageSource& src, dom::Uint8ClampedArray* const scopedArr)
+{
+ uint32_t width, height, depth;
+ if (!ValidateExtents(this, funcName, rawWidth, rawHeight, rawDepth, border, &width,
+ &height, &depth))
+ {
+ return nullptr;
+ }
+
+ if (src.mPboOffset) {
+ if (!mBoundPixelUnpackBuffer) {
+ ErrorInvalidOperation("%s: PACK_BUFFER must be non-null.", funcName);
+ return nullptr;
+ }
+
+ if (mBoundPixelUnpackBuffer->mNumActiveTFOs) {
+ ErrorInvalidOperation("%s: Buffer is bound to an active transform feedback"
+ " object.",
+ funcName);
+ return nullptr;
+ }
+
+ const auto& availBytes = mBoundPixelUnpackBuffer->ByteLength();
+ return FromPboOffset(this, funcName, target, width, height, depth,
+ *(src.mPboOffset), availBytes);
+ }
+
+ if (mBoundPixelUnpackBuffer) {
+ ErrorInvalidOperation("%s: PACK_BUFFER must be null.", funcName);
+ return nullptr;
}
- const uint32_t fullRows = elemHeight;
- const uint32_t tailPixels = 0;
- if (!mContext->ValidateUnpackPixels(funcName, fullRows, tailPixels, blob.get()))
+ if (src.mImageData) {
+ return FromImageData(this, funcName, target, width, height, depth,
+ *(src.mImageData), scopedArr);
+ }
+
+ if (src.mDomElem) {
+ return FromDomElem(funcName, target, width, height, depth, *(src.mDomElem),
+ src.mOut_error);
+ }
+
+ return FromView(this, funcName, target, width, height, depth, src.mView,
+ src.mViewElemOffset);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+static UniquePtr<webgl::TexUnpackBlob>
+ValidateTexOrSubImage(WebGLContext* webgl, const char* funcName, TexImageTarget target,
+ GLsizei rawWidth, GLsizei rawHeight, GLsizei rawDepth,
+ GLint border, const webgl::PackingInfo& pi,
+ const TexImageSource& src, dom::Uint8ClampedArray* const scopedArr)
+{
+ if (!ValidateUnpackInfo(webgl, funcName, pi))
+ return nullptr;
+
+ if (!ValidateViewType(webgl, funcName, pi.type, src))
+ return nullptr;
+
+ auto blob = webgl->From(funcName, target, rawWidth, rawHeight, rawDepth, border, src,
+ scopedArr);
+ if (!blob || !blob->Validate(webgl, funcName, pi))
+ return nullptr;
+
+ return Move(blob);
+}
+
+void
+WebGLTexture::TexImage(const char* funcName, TexImageTarget target, GLint level,
+ GLenum internalFormat, GLsizei width, GLsizei height,
+ GLsizei depth, GLint border, const webgl::PackingInfo& pi,
+ const TexImageSource& src)
+{
+ dom::RootedTypedArray<dom::Uint8ClampedArray> scopedArr(dom::RootingCx());
+ const auto blob = ValidateTexOrSubImage(mContext, funcName, target, width, height,
+ depth, border, pi, src, &scopedArr);
+ if (!blob)
return;
- TexOrSubImageBlob(isSubImage, funcName, target, level, internalFormat, xOffset,
- yOffset, zOffset, pi, blob.get());
+ TexImage(funcName, target, level, internalFormat, pi, blob.get());
}
-
-//////////////////////////////////////////////////////////////////////////////////////////
-
void
-WebGLTexture::TexOrSubImageBlob(bool isSubImage, const char* funcName,
- TexImageTarget target, GLint level, GLenum internalFormat,
- GLint xOffset, GLint yOffset, GLint zOffset,
- const webgl::PackingInfo& pi,
- const webgl::TexUnpackBlob* blob)
+WebGLTexture::TexSubImage(const char* funcName, TexImageTarget target, GLint level,
+ GLint xOffset, GLint yOffset, GLint zOffset, GLsizei width,
+ GLsizei height, GLsizei depth,
+ const webgl::PackingInfo& pi, const TexImageSource& src)
{
- if (isSubImage) {
- TexSubImage(funcName, target, level, xOffset, yOffset, zOffset, pi, blob);
- } else {
- TexImage(funcName, target, level, internalFormat, pi, blob);
- }
+ const GLint border = 0;
+ dom::RootedTypedArray<dom::Uint8ClampedArray> scopedArr(dom::RootingCx());
+ const auto blob = ValidateTexOrSubImage(mContext, funcName, target, width, height,
+ depth, border, pi, src, &scopedArr);
+ if (!blob)
+ return;
+
+ TexSubImage(funcName, target, level, xOffset, yOffset, zOffset, pi, blob.get());
}
//////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////
static bool
ValidateTexImage(WebGLContext* webgl, WebGLTexture* texture, const char* funcName,
TexImageTarget target, GLint level,
@@ -1444,36 +1344,72 @@ WebGLTexture::TexSubImage(const char* fu
if (uploadWillInitialize) {
imageInfo->SetIsDataInitialized(true, this);
}
}
////////////////////////////////////////
// CompressedTex(Sub)Image
+UniquePtr<webgl::TexUnpackBytes>
+WebGLContext::FromCompressed(const char* funcName, TexImageTarget target,
+ GLsizei rawWidth, GLsizei rawHeight, GLsizei rawDepth,
+ GLint border, const TexImageSource& src)
+{
+ uint32_t width, height, depth;
+ if (!ValidateExtents(this, funcName, rawWidth, rawHeight, rawDepth, border, &width,
+ &height, &depth))
+ {
+ return nullptr;
+ }
+
+ if (src.mPboOffset) {
+ if (!mBoundPixelUnpackBuffer) {
+ ErrorInvalidOperation("%s: PACK_BUFFER must be non-null.", funcName);
+ return nullptr;
+ }
+
+ if (mBoundPixelUnpackBuffer->mNumActiveTFOs) {
+ ErrorInvalidOperation("%s: Buffer is bound to an active transform feedback"
+ " object.",
+ funcName);
+ return nullptr;
+ }
+
+ const auto& availBytes = mBoundPixelUnpackBuffer->ByteLength();
+ return FromPboOffset(this, funcName, target, width, height, depth,
+ *(src.mPboOffset), availBytes);
+ }
+
+ if (mBoundPixelUnpackBuffer) {
+ ErrorInvalidOperation("%s: PACK_BUFFER must be null.", funcName);
+ return nullptr;
+ }
+
+ return FromView(this, funcName, target, width, height, depth, src.mView,
+ src.mViewElemOffset);
+}
+
void
WebGLTexture::CompressedTexImage(const char* funcName, TexImageTarget target, GLint level,
GLenum internalFormat, GLsizei rawWidth,
GLsizei rawHeight, GLsizei rawDepth, GLint border,
- const dom::ArrayBufferView& srcView,
- GLuint srcElemOffset)
+ const TexImageSource& src)
{
- uint32_t width, height, depth;
- if (!ValidateExtents(mContext, funcName, rawWidth, rawHeight, rawDepth, border,
- &width, &height, &depth))
- {
+ const auto blob = mContext->FromCompressed(funcName, target, rawWidth, rawHeight,
+ rawDepth, border, src);
+ if (!blob)
return;
- }
////////////////////////////////////
// Get dest info
WebGLTexture::ImageInfo* imageInfo;
- if (!ValidateTexImageSpecification(funcName, target, level, width, height, depth,
- &imageInfo))
+ if (!ValidateTexImageSpecification(funcName, target, level, blob->mWidth,
+ blob->mHeight, blob->mDepth, &imageInfo))
{
return;
}
MOZ_ASSERT(imageInfo);
auto usage = mContext->mFormatUsage->GetSizedTexUsage(internalFormat);
if (!usage) {
mContext->ErrorInvalidEnum("%s: Invalid internalFormat: 0x%04x", funcName,
@@ -1489,47 +1425,41 @@ WebGLTexture::CompressedTexImage(const c
}
if (!ValidateTargetForFormat(funcName, mContext, target, format))
return;
////////////////////////////////////
// Get source info
- const uint8_t* bytes;
- size_t byteLen;
- if (!mContext->ValidateArrayBufferView(funcName, srcView, srcElemOffset, 0,
- const_cast<uint8_t**>(&bytes), &byteLen))
- {
- return;
- }
-
- if (!ValidateCompressedTexUnpack(mContext, funcName, width, height, depth, format,
- byteLen))
+ if (!ValidateCompressedTexUnpack(mContext, funcName, blob->mWidth, blob->mHeight,
+ blob->mDepth, format, blob->mAvailBytes))
{
return;
}
////////////////////////////////////
// Check that source is compatible with dest
if (!ValidateCompressedTexImageRestrictions(funcName, mContext, target, level, format,
- width, height, depth))
+ blob->mWidth, blob->mHeight,
+ blob->mDepth))
{
return;
}
////////////////////////////////////
// Do the thing!
mContext->gl->MakeCurrent();
// Warning: Possibly shared memory. See bug 1225033.
GLenum error = DoCompressedTexImage(mContext->gl, target, level, internalFormat,
- width, height, depth, byteLen, bytes);
+ blob->mWidth, blob->mHeight, blob->mDepth,
+ blob->mAvailBytes, blob->mPtr);
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.",
@@ -1537,17 +1467,18 @@ WebGLTexture::CompressedTexImage(const c
mContext->ForceLoseContext();
return;
}
////////////////////////////////////
// Update our specification data.
const bool isDataInitialized = true;
- const ImageInfo newImageInfo(usage, width, height, depth, isDataInitialized);
+ const ImageInfo newImageInfo(usage, blob->mWidth, blob->mHeight, blob->mDepth,
+ isDataInitialized);
SetImageInfo(imageInfo, newImageInfo);
}
static inline bool
IsSubImageBlockAligned(const webgl::CompressedFormatInfo* compression,
const WebGLTexture::ImageInfo* imageInfo, GLint xOffset,
GLint yOffset, uint32_t width, uint32_t height)
{
@@ -1566,68 +1497,58 @@ 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& srcView,
- GLuint srcElemOffset)
+ const TexImageSource& src)
{
- uint32_t width, height, depth;
- if (!ValidateExtents(mContext, funcName, rawWidth, rawHeight, rawDepth, 0, &width,
- &height, &depth))
- {
+ const GLint border = 0;
+ const auto blob = mContext->FromCompressed(funcName, target, rawWidth, rawHeight,
+ rawDepth, border, src);
+ if (!blob)
return;
- }
////////////////////////////////////
// Get dest info
WebGLTexture::ImageInfo* imageInfo;
if (!ValidateTexImageSelection(funcName, target, level, xOffset, yOffset, zOffset,
- width, height, depth, &imageInfo))
+ blob->mWidth, blob->mHeight, blob->mDepth, &imageInfo))
{
return;
}
MOZ_ASSERT(imageInfo);
auto dstUsage = imageInfo->mFormat;
auto dstFormat = dstUsage->format;
////////////////////////////////////
// Get source info
- const uint8_t* bytes;
- size_t byteLen;
- if (!mContext->ValidateArrayBufferView(funcName, srcView, srcElemOffset, 0,
- const_cast<uint8_t**>(&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) {
mContext->ErrorInvalidOperation("%s: `format` must match the format of the"
" existing texture image.",
funcName);
return;
}
auto format = srcUsage->format;
MOZ_ASSERT(format == dstFormat);
- if (!ValidateCompressedTexUnpack(mContext, funcName, width, height, depth, format,
- byteLen))
+ if (!ValidateCompressedTexUnpack(mContext, funcName, blob->mWidth, blob->mHeight,
+ blob->mDepth, format, blob->mAvailBytes))
{
return;
}
////////////////////////////////////
// Check that source is compatible with dest
switch (format->compression->family) {
@@ -1637,56 +1558,58 @@ WebGLTexture::CompressedTexSubImage(cons
mContext->ErrorInvalidOperation("%s: Format does not allow sub-image"
" updates.", funcName);
return;
// Block-aligned:
case webgl::CompressionFamily::ES3: // Yes, the ES3 formats don't match the ES3
case webgl::CompressionFamily::S3TC: // default behavior.
if (!IsSubImageBlockAligned(dstFormat->compression, imageInfo, xOffset, yOffset,
- width, height))
+ blob->mWidth, blob->mHeight))
{
mContext->ErrorInvalidOperation("%s: Format requires block-aligned sub-image"
" updates.",
funcName);
return;
}
break;
// Full-only: (The ES3 default)
default: // PVRTC
if (xOffset || yOffset ||
- uint32_t(width) != imageInfo->mWidth ||
- uint32_t(height) != imageInfo->mHeight)
+ blob->mWidth != imageInfo->mWidth ||
+ blob->mHeight != imageInfo->mHeight)
{
mContext->ErrorInvalidOperation("%s: Format does not allow partial sub-image"
" updates.",
funcName);
return;
}
break;
}
////////////////////////////////////
// Do the thing!
mContext->gl->MakeCurrent();
bool uploadWillInitialize;
if (!EnsureImageDataInitializedForUpload(this, funcName, target, level, xOffset,
- yOffset, zOffset, width, height, depth,
- imageInfo, &uploadWillInitialize))
+ yOffset, zOffset, blob->mWidth,
+ blob->mHeight, blob->mDepth, imageInfo,
+ &uploadWillInitialize))
{
return;
}
// Warning: Possibly shared memory. See bug 1225033.
GLenum error = DoCompressedTexSubImage(mContext->gl, target, level, xOffset, yOffset,
- zOffset, width, height, depth,
- sizedUnpackFormat, byteLen, bytes);
+ 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;
}
if (error) {
MOZ_RELEASE_ASSERT(false, "GFX: We should have caught all other errors.");
mContext->GenerateWarning("%s: Unexpected error during texture upload. Context"
" lost.",