зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1313541 - Rewrite TexImageSource glue. - r=ethlin
MozReview-Commit-ID: 4zwNrobTcUf
This commit is contained in:
Родитель
4b2a875e8b
Коммит
cafb4ccac4
|
@ -131,6 +131,86 @@ FormatForPackingInfo(const PackingInfo& pi)
|
|||
|
||||
////////////////////
|
||||
|
||||
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)
|
||||
{
|
||||
|
@ -331,14 +411,25 @@ DoTexOrSubImage(bool isSubImage, gl::GLContext* gl, TexImageTarget target, GLint
|
|||
|
||||
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,
|
||||
|
@ -470,6 +561,14 @@ TexUnpackImage::TexUnpackImage(const WebGLContext* webgl, TexImageTarget target,
|
|||
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,
|
||||
|
@ -625,6 +724,14 @@ GetFormatForSurf(gfx::SourceSurface* surf, WebGLTexelFormat* const out_texelForm
|
|||
|
||||
//////////
|
||||
|
||||
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,
|
||||
|
|
|
@ -72,6 +72,8 @@ protected:
|
|||
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,
|
||||
|
@ -84,12 +86,16 @@ 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,
|
||||
|
@ -108,6 +114,8 @@ public:
|
|||
|
||||
~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,
|
||||
|
@ -124,6 +132,8 @@ public:
|
|||
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,
|
||||
|
|
|
@ -88,84 +88,138 @@ public:
|
|||
// 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);
|
||||
|
||||
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:
|
||||
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);
|
||||
}
|
||||
|
||||
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::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);
|
||||
|
||||
////
|
||||
|
||||
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&);
|
||||
ErrorResult&)
|
||||
{
|
||||
const TexImageSourceAdapter src(srcView, srcElemOffset);
|
||||
TexSubImage3D(target, level, xOffset, yOffset, zOffset, width, height, depth,
|
||||
unpackFormat, unpackType, src);
|
||||
}
|
||||
|
||||
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);
|
||||
|
|
|
@ -11,308 +11,18 @@
|
|||
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
|
||||
|
|
|
@ -195,6 +195,62 @@ struct 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
|
||||
|
@ -938,140 +994,185 @@ protected:
|
|||
|
||||
virtual bool IsTexParamValid(GLenum pname) const;
|
||||
|
||||
// Upload funcs
|
||||
////////////////////////////////////
|
||||
|
||||
public:
|
||||
void CompressedTexImage2D(GLenum texImageTarget, GLint level, GLenum internalFormat,
|
||||
template<typename T>
|
||||
void CompressedTexImage2D(GLenum target, 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&)
|
||||
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 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);
|
||||
|
||||
void TexSubImage2D(GLenum texImageTarget, GLint level, GLint xOffset, GLint yOffset,
|
||||
GLsizei width, GLsizei height, GLenum unpackFormat,
|
||||
GLenum unpackType, WebGLsizeiptr offset, ErrorResult&);
|
||||
|
||||
////////////////
|
||||
// dom::ImageData
|
||||
|
||||
void TexImage2D(GLenum texImageTarget, GLint level, GLenum internalFormat,
|
||||
GLenum unpackFormat, GLenum unpackType,
|
||||
const dom::ImageData* imageData, ErrorResult& out_error)
|
||||
void CopyTexSubImage2D(GLenum target, GLint level, GLint xOffset,
|
||||
GLint yOffset, GLint x, GLint y, GLsizei width,
|
||||
GLsizei height)
|
||||
{
|
||||
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 char funcName[] = "copyTexSubImage2D";
|
||||
const uint8_t funcDims = 2;
|
||||
const GLint zOffset = 0;
|
||||
CopyTexSubImage(funcName, funcDims, target, level, xOffset, yOffset, zOffset,
|
||||
x, y, width, height);
|
||||
}
|
||||
|
||||
void TexSubImage2D(GLenum texImageTarget, GLint level, GLint xOffset, GLint yOffset,
|
||||
GLenum unpackFormat, GLenum unpackType,
|
||||
const dom::ImageData* imageData, ErrorResult& out_error)
|
||||
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)
|
||||
{
|
||||
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);
|
||||
GLsizei width = 0;
|
||||
GLsizei height = 0;
|
||||
GLint border = 0;
|
||||
TexImage2D(target, level, internalFormat, width, height, border, unpackFormat,
|
||||
unpackType, src, 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,
|
||||
template<typename T>
|
||||
void TexSubImage2D(GLenum target, GLint level, GLint xOffset, GLint yOffset,
|
||||
GLenum unpackFormat, GLenum unpackType, const T& src,
|
||||
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, maybeSrc.Value(), 0, 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,
|
||||
GLsizei width, GLsizei height, GLenum unpackFormat,
|
||||
GLenum unpackType,
|
||||
const dom::ArrayBufferView& srcView, GLuint srcElemOffset,
|
||||
ErrorResult&);
|
||||
////
|
||||
|
||||
//////
|
||||
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 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);
|
||||
}
|
||||
|
||||
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";
|
||||
const uint8_t funcDims = 2;
|
||||
const GLsizei depth = 1;
|
||||
TexImage(funcName, funcDims, target, level, internalFormat, width, height, depth,
|
||||
border, unpackFormat, unpackType, src);
|
||||
}
|
||||
|
||||
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";
|
||||
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);
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
////////////////////////////////////
|
||||
// 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,
|
||||
|
@ -1088,10 +1189,19 @@ protected:
|
|||
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;
|
||||
|
@ -1468,10 +1578,12 @@ protected:
|
|||
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();
|
||||
|
|
|
@ -316,220 +316,44 @@ WebGLContext::TexParameter_base(GLenum rawTexTarget, GLenum pname, GLint* maybeI
|
|||
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);
|
||||
}
|
||||
|
||||
void
|
||||
WebGLContext::TexImage2D(GLenum rawTexImageTarget, GLint level, GLenum internalFormat,
|
||||
GLenum unpackFormat, GLenum unpackType, const dom::Element& elem,
|
||||
ErrorResult& out_error)
|
||||
{
|
||||
const char funcName[] = "texImage2D";
|
||||
const uint8_t funcDims = 2;
|
||||
|
||||
TexImageTarget target;
|
||||
WebGLTexture* tex;
|
||||
if (!ValidateTexImageTarget(this, funcName, funcDims, rawTexImageTarget, &target,
|
||||
&tex))
|
||||
{
|
||||
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))
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
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);
|
||||
border, src);
|
||||
}
|
||||
|
||||
void
|
||||
WebGLContext::CompressedTexSubImage2D(GLenum rawTexImageTarget, GLint level,
|
||||
GLint xOffset, GLint yOffset, GLsizei width,
|
||||
GLsizei height, GLenum sizedUnpackFormat,
|
||||
const dom::ArrayBufferView& srcView,
|
||||
GLuint srcElemOffset)
|
||||
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[] = "compressedTexSubImage2D";
|
||||
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;
|
||||
const GLsizei depth = 1;
|
||||
tex->CompressedTexSubImage(funcName, target, level, xOffset, yOffset, zOffset, width,
|
||||
height, depth, sizedUnpackFormat, srcView, srcElemOffset);
|
||||
height, depth, unpackFormat, src);
|
||||
}
|
||||
|
||||
////////////////////////////////////////
|
||||
// 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)
|
||||
{
|
||||
|
@ -538,35 +362,59 @@ WebGLContext::CopyTexImage2D(GLenum rawTexImageTarget, GLint level, GLenum inter
|
|||
|
||||
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
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
namespace mozilla {
|
||||
class ErrorResult;
|
||||
class WebGLContext;
|
||||
struct TexImageSource;
|
||||
|
||||
namespace dom {
|
||||
class Element;
|
||||
|
@ -232,28 +233,6 @@ 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* 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,
|
||||
|
@ -277,6 +256,13 @@ protected:
|
|||
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,
|
||||
|
@ -287,12 +273,12 @@ protected:
|
|||
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,
|
||||
|
|
|
@ -127,225 +127,85 @@ DoesJSTypeMatchUnpackType(GLenum unpackType, js::Scalar::Type jsType)
|
|||
}
|
||||
}
|
||||
|
||||
bool
|
||||
WebGLContext::ValidateUnpackPixels(const char* funcName, uint32_t fullRows,
|
||||
uint32_t tailPixels, webgl::TexUnpackBlob* blob)
|
||||
{
|
||||
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 (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);
|
||||
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;
|
||||
}
|
||||
|
||||
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)
|
||||
ValidateViewType(WebGLContext* webgl, const char* funcName, GLenum unpackType,
|
||||
const TexImageSource& src)
|
||||
{
|
||||
if (!width || !height || !depth)
|
||||
if (!src.mView)
|
||||
return true;
|
||||
const auto& view = *(src.mView);
|
||||
|
||||
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.");
|
||||
const auto& jsType = view.Type();
|
||||
if (!DoesJSTypeMatchUnpackType(unpackType, jsType)) {
|
||||
webgl->ErrorInvalidOperation("%s: ArrayBufferView type not compatible with"
|
||||
" `type`.",
|
||||
funcName);
|
||||
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)
|
||||
static bool
|
||||
ValidateUnpackInfo(WebGLContext* webgl, const char* funcName,
|
||||
const webgl::PackingInfo& pi)
|
||||
{
|
||||
uint32_t width, height, depth;
|
||||
if (!ValidateExtents(mContext, funcName, rawWidth, rawHeight, rawDepth, border,
|
||||
&width, &height, &depth))
|
||||
{
|
||||
return;
|
||||
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 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))
|
||||
{
|
||||
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);
|
||||
|
||||
if (bytes &&
|
||||
!ValidateUnpackBytes(mContext, funcName, width, height, depth, pi, byteCount,
|
||||
&blob))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
TexOrSubImageBlob(isSubImage, funcName, target, level, internalFormat, xOffset,
|
||||
yOffset, zOffset, pi, &blob);
|
||||
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,
|
||||
WebGLsizeiptr offset)
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
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)
|
||||
{
|
||||
uint32_t width, height, depth;
|
||||
if (!ValidateExtents(mContext, funcName, rawWidth, rawHeight, rawDepth, border,
|
||||
&width, &height, &depth))
|
||||
{
|
||||
return;
|
||||
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 nullptr;
|
||||
}
|
||||
}
|
||||
return MakeUnique<webgl::TexUnpackBytes>(webgl, target, width, height, depth,
|
||||
isClientData, bytes, availByteCount);
|
||||
}
|
||||
|
||||
static UniquePtr<webgl::TexUnpackBytes>
|
||||
FromPboOffset(WebGLContext* webgl, const char* funcName, TexImageTarget target,
|
||||
uint32_t width, uint32_t height, uint32_t depth, WebGLsizeiptr pboOffset,
|
||||
size_t availBufferBytes)
|
||||
{
|
||||
if (pboOffset < 0) {
|
||||
webgl->ErrorInvalidValue("%s: offset cannot be negative.", funcName);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
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;
|
||||
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*)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);
|
||||
const auto ptr = (const uint8_t*)pboOffset;
|
||||
return MakeUnique<webgl::TexUnpackBytes>(webgl, target, width, height, depth,
|
||||
isClientData, ptr, availBufferBytes);
|
||||
}
|
||||
|
||||
////////////////////////////////////////
|
||||
// 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());
|
||||
|
@ -363,83 +223,46 @@ FromImageData(WebGLContext* webgl, const char* funcName, GLenum unpackType,
|
|||
|
||||
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();
|
||||
}
|
||||
////
|
||||
|
||||
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 (!width) {
|
||||
width = imageData.Width();
|
||||
}
|
||||
|
||||
// Eventually, these will be args.
|
||||
const uint32_t width = imageData.Width();
|
||||
const uint32_t height = imageData.Height();
|
||||
const uint32_t depth = 1;
|
||||
if (!height) {
|
||||
height = imageData.Height();
|
||||
}
|
||||
|
||||
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.
|
||||
|
@ -469,18 +292,20 @@ WebGLTexture::TexOrSubImage(bool isSubImage, const char* funcName, TexImageTarge
|
|||
|
||||
//////
|
||||
|
||||
// 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);
|
||||
}
|
||||
|
||||
//////
|
||||
|
@ -491,13 +316,12 @@ WebGLTexture::TexOrSubImage(bool isSubImage, const char* funcName, TexImageTarge
|
|||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -505,52 +329,128 @@ WebGLTexture::TexOrSubImage(bool isSubImage, const char* funcName, TexImageTarge
|
|||
// 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);
|
||||
}
|
||||
|
||||
const uint32_t fullRows = elemHeight;
|
||||
const uint32_t tailPixels = 0;
|
||||
if (!mContext->ValidateUnpackPixels(funcName, fullRows, tailPixels, blob.get()))
|
||||
return;
|
||||
|
||||
TexOrSubImageBlob(isSubImage, funcName, target, level, internalFormat, xOffset,
|
||||
yOffset, zOffset, pi, blob.get());
|
||||
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;
|
||||
}
|
||||
|
||||
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::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::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)
|
||||
{
|
||||
if (isSubImage) {
|
||||
TexSubImage(funcName, target, level, xOffset, yOffset, zOffset, pi, blob);
|
||||
} else {
|
||||
TexImage(funcName, target, level, internalFormat, pi, blob);
|
||||
}
|
||||
dom::RootedTypedArray<dom::Uint8ClampedArray> scopedArr(dom::RootingCx());
|
||||
const auto blob = ValidateTexOrSubImage(mContext, funcName, target, width, height,
|
||||
depth, border, pi, src, &scopedArr);
|
||||
if (!blob)
|
||||
return;
|
||||
|
||||
TexImage(funcName, target, level, internalFormat, pi, blob.get());
|
||||
}
|
||||
|
||||
void
|
||||
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)
|
||||
{
|
||||
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());
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -1449,26 +1349,62 @@ WebGLTexture::TexSubImage(const char* funcName, TexImageTarget target, GLint lev
|
|||
////////////////////////////////////////
|
||||
// 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;
|
||||
}
|
||||
|
@ -1494,16 +1430,8 @@ WebGLTexture::CompressedTexImage(const char* funcName, TexImageTarget target, GL
|
|||
////////////////////////////////////
|
||||
// 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;
|
||||
}
|
||||
|
@ -1512,7 +1440,8 @@ WebGLTexture::CompressedTexImage(const char* funcName, TexImageTarget target, GL
|
|||
// Check that source is compatible with dest
|
||||
|
||||
if (!ValidateCompressedTexImageRestrictions(funcName, mContext, target, level, format,
|
||||
width, height, depth))
|
||||
blob->mWidth, blob->mHeight,
|
||||
blob->mDepth))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
@ -1524,7 +1453,8 @@ WebGLTexture::CompressedTexImage(const char* funcName, TexImageTarget target, GL
|
|||
|
||||
// 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;
|
||||
|
@ -1542,7 +1472,8 @@ WebGLTexture::CompressedTexImage(const char* funcName, TexImageTarget target, GL
|
|||
// 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);
|
||||
}
|
||||
|
||||
|
@ -1571,22 +1502,20 @@ 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;
|
||||
}
|
||||
|
@ -1598,14 +1527,6 @@ WebGLTexture::CompressedTexSubImage(const char* funcName, TexImageTarget target,
|
|||
////////////////////////////////////
|
||||
// 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);
|
||||
|
@ -1621,8 +1542,8 @@ WebGLTexture::CompressedTexSubImage(const char* funcName, TexImageTarget target,
|
|||
|
||||
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;
|
||||
}
|
||||
|
@ -1642,7 +1563,7 @@ WebGLTexture::CompressedTexSubImage(const char* funcName, TexImageTarget target,
|
|||
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.",
|
||||
|
@ -1654,8 +1575,8 @@ WebGLTexture::CompressedTexSubImage(const char* funcName, TexImageTarget target,
|
|||
// 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.",
|
||||
|
@ -1672,16 +1593,18 @@ WebGLTexture::CompressedTexSubImage(const char* funcName, TexImageTarget target,
|
|||
|
||||
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;
|
||||
|
|
Загрузка…
Ссылка в новой задаче