Bug 1478909 - Make funcName implicit for WebGL calls. - r=kvark

MozReview-Commit-ID: Gv77SnHZcGb
This commit is contained in:
Jeff Gilbert 2018-07-26 21:46:33 -07:00
Родитель 14af3949fc
Коммит 8e0436b208
55 изменённых файлов: 1889 добавлений и 1926 удалений

Просмотреть файл

@ -67,12 +67,10 @@ IsPIValidForDOM(const webgl::PackingInfo& pi)
} }
static bool static bool
ValidatePIForDOM(WebGLContext* webgl, const char* funcName, ValidatePIForDOM(WebGLContext* webgl, const webgl::PackingInfo& pi)
const webgl::PackingInfo& pi)
{ {
if (!IsPIValidForDOM(pi)) { if (!IsPIValidForDOM(pi)) {
webgl->ErrorInvalidOperation("%s: Format or type is invalid for DOM sources.", webgl->ErrorInvalidOperation("Format or type is invalid for DOM sources.");
funcName);
return false; return false;
} }
return true; return true;
@ -179,7 +177,7 @@ FormatForPackingInfo(const PackingInfo& pi)
//////////////////// ////////////////////
static bool static bool
ValidateUnpackPixels(WebGLContext* webgl, const char* funcName, uint32_t fullRows, ValidateUnpackPixels(WebGLContext* webgl, uint32_t fullRows,
uint32_t tailPixels, webgl::TexUnpackBlob* blob) uint32_t tailPixels, webgl::TexUnpackBlob* blob)
{ {
if (!blob->mWidth || !blob->mHeight || !blob->mDepth) if (!blob->mWidth || !blob->mHeight || !blob->mDepth)
@ -187,14 +185,13 @@ ValidateUnpackPixels(WebGLContext* webgl, const char* funcName, uint32_t fullRow
const auto usedPixelsPerRow = CheckedUint32(blob->mSkipPixels) + blob->mWidth; const auto usedPixelsPerRow = CheckedUint32(blob->mSkipPixels) + blob->mWidth;
if (!usedPixelsPerRow.isValid() || usedPixelsPerRow.value() > blob->mRowLength) { if (!usedPixelsPerRow.isValid() || usedPixelsPerRow.value() > blob->mRowLength) {
webgl->ErrorInvalidOperation("%s: UNPACK_SKIP_PIXELS + width >" webgl->ErrorInvalidOperation("UNPACK_SKIP_PIXELS + width >"
" UNPACK_ROW_LENGTH.", " UNPACK_ROW_LENGTH.");
funcName);
return false; return false;
} }
if (blob->mHeight > blob->mImageHeight) { if (blob->mHeight > blob->mImageHeight) {
webgl->ErrorInvalidOperation("%s: height > UNPACK_IMAGE_HEIGHT.", funcName); webgl->ErrorInvalidOperation("height > UNPACK_IMAGE_HEIGHT.");
return false; return false;
} }
@ -211,8 +208,7 @@ ValidateUnpackPixels(WebGLContext* webgl, const char* funcName, uint32_t fullRow
const auto fullRowsNeeded = skipFullRows + usedFullRows; const auto fullRowsNeeded = skipFullRows + usedFullRows;
if (!fullRowsNeeded.isValid()) { if (!fullRowsNeeded.isValid()) {
webgl->ErrorOutOfMemory("%s: Invalid calculation for required row count.", webgl->ErrorOutOfMemory("Invalid calculation for required row count.");
funcName);
return false; return false;
} }
@ -224,16 +220,16 @@ ValidateUnpackPixels(WebGLContext* webgl, const char* funcName, uint32_t fullRow
return true; return true;
} }
webgl->ErrorInvalidOperation("%s: Desired upload requires more data than is" webgl->ErrorInvalidOperation("Desired upload requires more data than is"
" available: (%u rows plus %u pixels needed, %u rows" " available: (%u rows plus %u pixels needed, %u rows"
" plus %u pixels available)", " plus %u pixels available)",
funcName, fullRowsNeeded.value(), fullRowsNeeded.value(),
usedPixelsPerRow.value(), fullRows, tailPixels); usedPixelsPerRow.value(), fullRows, tailPixels);
return false; return false;
} }
static bool static bool
ValidateUnpackBytes(WebGLContext* webgl, const char* funcName, ValidateUnpackBytes(WebGLContext* webgl,
const webgl::PackingInfo& pi, size_t availByteCount, const webgl::PackingInfo& pi, size_t availByteCount,
webgl::TexUnpackBlob* blob) webgl::TexUnpackBlob* blob)
{ {
@ -246,14 +242,14 @@ ValidateUnpackBytes(WebGLContext* webgl, const char* funcName,
const auto fullRows = availByteCount / rowStride; const auto fullRows = availByteCount / rowStride;
if (!fullRows.isValid()) { if (!fullRows.isValid()) {
webgl->ErrorOutOfMemory("%s: Unacceptable upload size calculated.", funcName); webgl->ErrorOutOfMemory("Unacceptable upload size calculated.");
return false; return false;
} }
const auto bodyBytes = fullRows.value() * rowStride.value(); const auto bodyBytes = fullRows.value() * rowStride.value();
const auto tailPixels = (availByteCount - bodyBytes) / bytesPerPixel; const auto tailPixels = (availByteCount - bodyBytes) / bytesPerPixel;
return ValidateUnpackPixels(webgl, funcName, fullRows.value(), tailPixels, blob); return ValidateUnpackPixels(webgl, fullRows.value(), tailPixels, blob);
} }
//////////////////// ////////////////////
@ -313,7 +309,7 @@ HasColorAndAlpha(const WebGLTexelFormat format)
} }
bool bool
TexUnpackBlob::ConvertIfNeeded(WebGLContext* webgl, const char* funcName, TexUnpackBlob::ConvertIfNeeded(WebGLContext* webgl,
const uint32_t rowLength, const uint32_t rowCount, const uint32_t rowLength, const uint32_t rowCount,
WebGLTexelFormat srcFormat, WebGLTexelFormat srcFormat,
const uint8_t* const srcBegin, const ptrdiff_t srcStride, const uint8_t* const srcBegin, const ptrdiff_t srcStride,
@ -346,18 +342,17 @@ TexUnpackBlob::ConvertIfNeeded(WebGLContext* webgl, const char* funcName,
const auto dstOrigin = gl::OriginPos::BottomLeft; const auto dstOrigin = gl::OriginPos::BottomLeft;
if (srcFormat != dstFormat) { if (srcFormat != dstFormat) {
webgl->GeneratePerfWarning("%s: Conversion requires pixel reformatting. (%u->%u)", webgl->GeneratePerfWarning("Conversion requires pixel reformatting. (%u->%u)",
funcName, uint32_t(srcFormat), uint32_t(srcFormat),
uint32_t(dstFormat)); uint32_t(dstFormat));
} else if (fnHasPremultMismatch()) { } else if (fnHasPremultMismatch()) {
webgl->GeneratePerfWarning("%s: Conversion requires change in" webgl->GeneratePerfWarning("Conversion requires change in"
" alpha-premultiplication.", " alpha-premultiplication.");
funcName);
} else if (srcOrigin != dstOrigin) { } else if (srcOrigin != dstOrigin) {
webgl->GeneratePerfWarning("%s: Conversion requires y-flip.", funcName); webgl->GeneratePerfWarning("Conversion requires y-flip.");
} else if (srcStride != dstStride) { } else if (srcStride != dstStride) {
webgl->GeneratePerfWarning("%s: Conversion requires change in stride. (%u->%u)", webgl->GeneratePerfWarning("Conversion requires change in stride. (%u->%u)",
funcName, uint32_t(srcStride), uint32_t(dstStride)); uint32_t(srcStride), uint32_t(dstStride));
} else { } else {
return true; return true;
} }
@ -366,13 +361,13 @@ TexUnpackBlob::ConvertIfNeeded(WebGLContext* webgl, const char* funcName,
const auto dstTotalBytes = CheckedUint32(rowCount) * dstStride; const auto dstTotalBytes = CheckedUint32(rowCount) * dstStride;
if (!dstTotalBytes.isValid()) { if (!dstTotalBytes.isValid()) {
webgl->ErrorOutOfMemory("%s: Calculation failed.", funcName); webgl->ErrorOutOfMemory("Calculation failed.");
return false; return false;
} }
UniqueBuffer dstBuffer = calloc(1, dstTotalBytes.value()); UniqueBuffer dstBuffer = calloc(1, dstTotalBytes.value());
if (!dstBuffer.get()) { if (!dstBuffer.get()) {
webgl->ErrorOutOfMemory("%s: Failed to allocate dest buffer.", funcName); webgl->ErrorOutOfMemory("Failed to allocate dest buffer.");
return false; return false;
} }
const auto dstBegin = static_cast<uint8_t*>(dstBuffer.get()); const auto dstBegin = static_cast<uint8_t*>(dstBuffer.get());
@ -386,7 +381,7 @@ TexUnpackBlob::ConvertIfNeeded(WebGLContext* webgl, const char* funcName,
dstBegin, dstStride, dstOrigin, dstFormat, dstIsPremult, dstBegin, dstStride, dstOrigin, dstFormat, dstIsPremult,
&wasTrivial)) &wasTrivial))
{ {
webgl->ErrorImplementationBug("%s: ConvertImage failed.", funcName); webgl->ErrorImplementationBug("ConvertImage failed.");
return false; return false;
} }
@ -423,17 +418,16 @@ TexUnpackBytes::TexUnpackBytes(const WebGLContext* webgl, TexImageTarget target,
{ } { }
bool bool
TexUnpackBytes::Validate(WebGLContext* webgl, const char* funcName, TexUnpackBytes::Validate(WebGLContext* webgl, const webgl::PackingInfo& pi)
const webgl::PackingInfo& pi)
{ {
if (mIsClientData && !mPtr) if (mIsClientData && !mPtr)
return true; return true;
return ValidateUnpackBytes(webgl, funcName, pi, mAvailBytes, this); return ValidateUnpackBytes(webgl, pi, mAvailBytes, this);
} }
bool bool
TexUnpackBytes::TexOrSubImage(bool isSubImage, bool needsRespec, const char* funcName, TexUnpackBytes::TexOrSubImage(bool isSubImage, bool needsRespec,
WebGLTexture* tex, TexImageTarget target, GLint level, WebGLTexture* tex, TexImageTarget target, GLint level,
const webgl::DriverUnpackInfo* dui, GLint xOffset, const webgl::DriverUnpackInfo* dui, GLint xOffset,
GLint yOffset, GLint zOffset, const webgl::PackingInfo& pi, GLint yOffset, GLint zOffset, const webgl::PackingInfo& pi,
@ -463,20 +457,18 @@ TexUnpackBytes::TexOrSubImage(bool isSubImage, bool needsRespec, const char* fun
webgl->mPixelStore_UnpackSkipRows || webgl->mPixelStore_UnpackSkipRows ||
webgl->mPixelStore_UnpackSkipPixels) webgl->mPixelStore_UnpackSkipPixels)
{ {
webgl->ErrorInvalidOperation("%s: Non-DOM-Element uploads with alpha-premult" webgl->ErrorInvalidOperation("Non-DOM-Element uploads with alpha-premult"
" or y-flip do not support subrect selection.", " or y-flip do not support subrect selection.");
funcName);
return false; return false;
} }
webgl->GenerateWarning("%s: Alpha-premult and y-flip are deprecated for" webgl->GenerateWarning("Alpha-premult and y-flip are deprecated for"
" non-DOM-Element uploads.", " non-DOM-Element uploads.");
funcName);
const uint32_t rowLength = mWidth; const uint32_t rowLength = mWidth;
const uint32_t rowCount = mHeight * mDepth; const uint32_t rowCount = mHeight * mDepth;
const auto stride = RoundUpToMultipleOf(rowLength * bytesPerPixel, mAlignment); const auto stride = RoundUpToMultipleOf(rowLength * bytesPerPixel, mAlignment);
if (!ConvertIfNeeded(webgl, funcName, rowLength, rowCount, format, mPtr, stride, if (!ConvertIfNeeded(webgl, rowLength, rowCount, format, mPtr, stride,
format, stride, &uploadPtr, &tempBuffer)) format, stride, &uploadPtr, &tempBuffer))
{ {
return false; return false;
@ -489,10 +481,9 @@ TexUnpackBytes::TexOrSubImage(bool isSubImage, bool needsRespec, const char* fun
bool useParanoidHandling = false; bool useParanoidHandling = false;
if (mNeedsExactUpload && webgl->mBoundPixelUnpackBuffer) { if (mNeedsExactUpload && webgl->mBoundPixelUnpackBuffer) {
webgl->GenerateWarning("%s: Uploads from a buffer with a final row with a byte" webgl->GenerateWarning("Uploads from a buffer with a final row with a byte"
" count smaller than the row stride can incur extra" " count smaller than the row stride can incur extra"
" overhead.", " overhead.");
funcName);
if (gl->WorkAroundDriverBugs()) { if (gl->WorkAroundDriverBugs()) {
useParanoidHandling |= (gl->Vendor() == gl::GLVendor::NVIDIA); useParanoidHandling |= (gl->Vendor() == gl::GLVendor::NVIDIA);
@ -601,18 +592,17 @@ TexUnpackImage::~TexUnpackImage()
{ } { }
bool bool
TexUnpackImage::Validate(WebGLContext* webgl, const char* funcName, TexUnpackImage::Validate(WebGLContext* webgl, const webgl::PackingInfo& pi)
const webgl::PackingInfo& pi)
{ {
if (!ValidatePIForDOM(webgl, funcName, pi)) if (!ValidatePIForDOM(webgl, pi))
return false; return false;
const auto fullRows = mImage->GetSize().height; const auto fullRows = mImage->GetSize().height;
return ValidateUnpackPixels(webgl, funcName, fullRows, 0, this); return ValidateUnpackPixels(webgl, fullRows, 0, this);
} }
bool bool
TexUnpackImage::TexOrSubImage(bool isSubImage, bool needsRespec, const char* funcName, TexUnpackImage::TexOrSubImage(bool isSubImage, bool needsRespec,
WebGLTexture* tex, TexImageTarget target, GLint level, WebGLTexture* tex, TexImageTarget target, GLint level,
const webgl::DriverUnpackInfo* dui, GLint xOffset, const webgl::DriverUnpackInfo* dui, GLint xOffset,
GLint yOffset, GLint zOffset, const webgl::PackingInfo& pi, GLint yOffset, GLint zOffset, const webgl::PackingInfo& pi,
@ -714,8 +704,8 @@ TexUnpackImage::TexOrSubImage(bool isSubImage, bool needsRespec, const char* fun
return true; return true;
} while (false); } while (false);
const nsPrintfCString perfMsg("%s: Failed to hit GPU-copy fast-path: %s (src type %u)", const nsPrintfCString perfMsg("Failed to hit GPU-copy fast-path: %s (src type %u)",
funcName, fallbackReason, uint32_t(mImage->GetFormat())); fallbackReason, uint32_t(mImage->GetFormat()));
if (webgl->mPixelStore_RequireFastPath) { if (webgl->mPixelStore_RequireFastPath) {
webgl->ErrorInvalidOperation("%s", perfMsg.BeginReading()); webgl->ErrorInvalidOperation("%s", perfMsg.BeginReading());
@ -733,16 +723,15 @@ TexUnpackImage::TexOrSubImage(bool isSubImage, bool needsRespec, const char* fun
dataSurf = surf->GetDataSurface(); dataSurf = surf->GetDataSurface();
} }
if (!dataSurf) { if (!dataSurf) {
webgl->ErrorOutOfMemory("%s: GetAsSourceSurface or GetDataSurface failed after" webgl->ErrorOutOfMemory("GetAsSourceSurface or GetDataSurface failed after"
" blit failed for TexUnpackImage.", " blit failed for TexUnpackImage.");
funcName);
return false; return false;
} }
const TexUnpackSurface surfBlob(webgl, target, mWidth, mHeight, mDepth, dataSurf, const TexUnpackSurface surfBlob(webgl, target, mWidth, mHeight, mDepth, dataSurf,
mSrcAlphaType); mSrcAlphaType);
return surfBlob.TexOrSubImage(isSubImage, needsRespec, funcName, tex, target, level, return surfBlob.TexOrSubImage(isSubImage, needsRespec, tex, target, level,
dui, xOffset, yOffset, zOffset, pi, out_error); dui, xOffset, yOffset, zOffset, pi, out_error);
} }
@ -812,18 +801,17 @@ GetFormatForSurf(gfx::SourceSurface* surf, WebGLTexelFormat* const out_texelForm
////////// //////////
bool bool
TexUnpackSurface::Validate(WebGLContext* webgl, const char* funcName, TexUnpackSurface::Validate(WebGLContext* webgl, const webgl::PackingInfo& pi)
const webgl::PackingInfo& pi)
{ {
if (!ValidatePIForDOM(webgl, funcName, pi)) if (!ValidatePIForDOM(webgl, pi))
return false; return false;
const auto fullRows = mSurf->GetSize().height; const auto fullRows = mSurf->GetSize().height;
return ValidateUnpackPixels(webgl, funcName, fullRows, 0, this); return ValidateUnpackPixels(webgl, fullRows, 0, this);
} }
bool bool
TexUnpackSurface::TexOrSubImage(bool isSubImage, bool needsRespec, const char* funcName, TexUnpackSurface::TexOrSubImage(bool isSubImage, bool needsRespec,
WebGLTexture* tex, TexImageTarget target, GLint level, WebGLTexture* tex, TexImageTarget target, GLint level,
const webgl::DriverUnpackInfo* dui, GLint xOffset, const webgl::DriverUnpackInfo* dui, GLint xOffset,
GLint yOffset, GLint zOffset, const webgl::PackingInfo& dstPI, GLint yOffset, GLint zOffset, const webgl::PackingInfo& dstPI,
@ -844,15 +832,15 @@ TexUnpackSurface::TexOrSubImage(bool isSubImage, bool needsRespec, const char* f
WebGLTexelFormat srcFormat; WebGLTexelFormat srcFormat;
uint8_t srcBPP; uint8_t srcBPP;
if (!GetFormatForSurf(mSurf, &srcFormat, &srcBPP)) { if (!GetFormatForSurf(mSurf, &srcFormat, &srcBPP)) {
webgl->ErrorImplementationBug("%s: GetFormatForSurf failed for" webgl->ErrorImplementationBug("GetFormatForSurf failed for"
" WebGLTexelFormat::%u.", " WebGLTexelFormat::%u.",
funcName, uint32_t(mSurf->GetFormat())); uint32_t(mSurf->GetFormat()));
return false; return false;
} }
gfx::DataSourceSurface::ScopedMap map(mSurf, gfx::DataSourceSurface::MapType::READ); gfx::DataSourceSurface::ScopedMap map(mSurf, gfx::DataSourceSurface::MapType::READ);
if (!map.IsMapped()) { if (!map.IsMapped()) {
webgl->ErrorOutOfMemory("%s: Failed to map source surface for upload.", funcName); webgl->ErrorOutOfMemory("Failed to map source surface for upload.");
return false; return false;
} }
@ -879,7 +867,7 @@ TexUnpackSurface::TexOrSubImage(bool isSubImage, bool needsRespec, const char* f
const uint8_t* dstBegin = srcBegin; const uint8_t* dstBegin = srcBegin;
UniqueBuffer tempBuffer; UniqueBuffer tempBuffer;
if (!ConvertIfNeeded(webgl, funcName, rowLength, rowCount, srcFormat, srcBegin, if (!ConvertIfNeeded(webgl, rowLength, rowCount, srcFormat, srcBegin,
srcStride, dstFormat, dstStride, &dstBegin, &tempBuffer)) srcStride, dstFormat, dstStride, &dstBegin, &tempBuffer))
{ {
return false; return false;

Просмотреть файл

@ -64,7 +64,7 @@ public:
virtual ~TexUnpackBlob() { } virtual ~TexUnpackBlob() { }
protected: protected:
bool ConvertIfNeeded(WebGLContext* webgl, const char* funcName, bool ConvertIfNeeded(WebGLContext* webgl,
const uint32_t rowLength, const uint32_t rowCount, const uint32_t rowLength, const uint32_t rowCount,
WebGLTexelFormat srcFormat, WebGLTexelFormat srcFormat,
const uint8_t* const srcBegin, const ptrdiff_t srcStride, const uint8_t* const srcBegin, const ptrdiff_t srcStride,
@ -76,13 +76,12 @@ protected:
public: public:
virtual bool HasData() const { return true; } virtual bool HasData() const { return true; }
virtual bool Validate(WebGLContext* webgl, const char* funcName, virtual bool Validate(WebGLContext* webgl, const webgl::PackingInfo& pi) = 0;
const webgl::PackingInfo& pi) = 0;
// Returns false when we've generated a WebGL error. // Returns false when we've generated a WebGL error.
// Returns true but with a non-zero *out_error if we still need to generate a WebGL // Returns true but with a non-zero *out_error if we still need to generate a WebGL
// error. // error.
virtual bool TexOrSubImage(bool isSubImage, bool needsRespec, const char* funcName, virtual bool TexOrSubImage(bool isSubImage, bool needsRespec,
WebGLTexture* tex, TexImageTarget target, GLint level, WebGLTexture* tex, TexImageTarget target, GLint level,
const webgl::DriverUnpackInfo* dui, GLint xOffset, const webgl::DriverUnpackInfo* dui, GLint xOffset,
GLint yOffset, GLint zOffset, GLint yOffset, GLint zOffset,
@ -102,9 +101,9 @@ public:
virtual bool HasData() const override { return !mIsClientData || bool(mPtr); } virtual bool HasData() const override { return !mIsClientData || bool(mPtr); }
virtual bool Validate(WebGLContext* webgl, const char* funcName, virtual bool Validate(WebGLContext* webgl,
const webgl::PackingInfo& pi) override; const webgl::PackingInfo& pi) override;
virtual bool TexOrSubImage(bool isSubImage, bool needsRespec, const char* funcName, virtual bool TexOrSubImage(bool isSubImage, bool needsRespec,
WebGLTexture* tex, TexImageTarget target, GLint level, WebGLTexture* tex, TexImageTarget target, GLint level,
const webgl::DriverUnpackInfo* dui, GLint xOffset, const webgl::DriverUnpackInfo* dui, GLint xOffset,
GLint yOffset, GLint zOffset, GLint yOffset, GLint zOffset,
@ -122,9 +121,9 @@ public:
~TexUnpackImage(); // Prevent needing to define layers::Image in the header. ~TexUnpackImage(); // Prevent needing to define layers::Image in the header.
virtual bool Validate(WebGLContext* webgl, const char* funcName, virtual bool Validate(WebGLContext* webgl,
const webgl::PackingInfo& pi) override; const webgl::PackingInfo& pi) override;
virtual bool TexOrSubImage(bool isSubImage, bool needsRespec, const char* funcName, virtual bool TexOrSubImage(bool isSubImage, bool needsRespec,
WebGLTexture* tex, TexImageTarget target, GLint level, WebGLTexture* tex, TexImageTarget target, GLint level,
const webgl::DriverUnpackInfo* dui, GLint xOffset, const webgl::DriverUnpackInfo* dui, GLint xOffset,
GLint yOffset, GLint zOffset, GLint yOffset, GLint zOffset,
@ -140,9 +139,9 @@ public:
uint32_t height, uint32_t depth, gfx::DataSourceSurface* surf, uint32_t height, uint32_t depth, gfx::DataSourceSurface* surf,
gfxAlphaType srcAlphaType); gfxAlphaType srcAlphaType);
virtual bool Validate(WebGLContext* webgl, const char* funcName, virtual bool Validate(WebGLContext* webgl,
const webgl::PackingInfo& pi) override; const webgl::PackingInfo& pi) override;
virtual bool TexOrSubImage(bool isSubImage, bool needsRespec, const char* funcName, virtual bool TexOrSubImage(bool isSubImage, bool needsRespec,
WebGLTexture* tex, TexImageTarget target, GLint level, WebGLTexture* tex, TexImageTarget target, GLint level,
const webgl::DriverUnpackInfo* dui, GLint xOffset, const webgl::DriverUnpackInfo* dui, GLint xOffset,
GLint yOffset, GLint zOffset, GLint yOffset, GLint zOffset,

Просмотреть файл

@ -82,8 +82,12 @@ public:
void GetInternalformatParameter(JSContext*, GLenum target, GLenum internalformat, void GetInternalformatParameter(JSContext*, GLenum target, GLenum internalformat,
GLenum pname, JS::MutableHandleValue retval, GLenum pname, JS::MutableHandleValue retval,
ErrorResult& rv); ErrorResult& rv);
void RenderbufferStorageMultisample(GLenum target, GLsizei samples, GLenum internalformat, void RenderbufferStorageMultisample(GLenum target, GLsizei samples, GLenum internalFormat,
GLsizei width, GLsizei height); GLsizei width, GLsizei height)
{
const FuncScope funcScope(*this, "renderbufferStorageMultisample");
RenderbufferStorage_base(target, samples, internalFormat, width, height);
}
// ------------------------------------------------------------------------- // -------------------------------------------------------------------------
@ -92,24 +96,22 @@ public:
void TexStorage2D(GLenum target, GLsizei levels, GLenum internalFormat, GLsizei width, void TexStorage2D(GLenum target, GLsizei levels, GLenum internalFormat, GLsizei width,
GLsizei height) GLsizei height)
{ {
const char funcName[] = "TexStorage2D"; const FuncScope funcScope(*this, "TexStorage2D");
const uint8_t funcDims = 2; const uint8_t funcDims = 2;
const GLsizei depth = 1; const GLsizei depth = 1;
TexStorage(funcName, funcDims, target, levels, internalFormat, width, height, TexStorage(funcDims, target, levels, internalFormat, width, height, depth);
depth);
} }
void TexStorage3D(GLenum target, GLsizei levels, GLenum internalFormat, GLsizei width, void TexStorage3D(GLenum target, GLsizei levels, GLenum internalFormat, GLsizei width,
GLsizei height, GLsizei depth) GLsizei height, GLsizei depth)
{ {
const char funcName[] = "TexStorage3D"; const FuncScope funcScope(*this, "TexStorage3D");
const uint8_t funcDims = 3; const uint8_t funcDims = 3;
TexStorage(funcName, funcDims, target, levels, internalFormat, width, height, TexStorage(funcDims, target, levels, internalFormat, width, height, depth);
depth);
} }
protected: protected:
void TexStorage(const char* funcName, uint8_t funcDims, GLenum target, GLsizei levels, void TexStorage(uint8_t funcDims, GLenum target, GLsizei levels,
GLenum internalFormat, GLsizei width, GLsizei height, GLsizei depth); GLenum internalFormat, GLsizei width, GLsizei height, GLsizei depth);
//////////////////////////////////// ////////////////////////////////////
@ -119,10 +121,10 @@ public:
GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei width, GLsizei height, GLsizei depth, GLint border,
GLsizei imageSize, WebGLintptr offset) GLsizei imageSize, WebGLintptr offset)
{ {
const char funcName[] = "compressedTexImage3D"; const FuncScope funcScope(*this, "compressedTexImage3D");
const uint8_t funcDims = 3; const uint8_t funcDims = 3;
const TexImageSourceAdapter src(&offset, 0, 0); const TexImageSourceAdapter src(&offset, 0, 0);
CompressedTexImage(funcName, funcDims, target, level, internalFormat, width, CompressedTexImage(funcDims, target, level, internalFormat, width,
height, depth, border, src, Some(imageSize)); height, depth, border, src, Some(imageSize));
} }
@ -132,10 +134,10 @@ public:
const T& anySrc, GLuint viewElemOffset = 0, const T& anySrc, GLuint viewElemOffset = 0,
GLuint viewElemLengthOverride = 0) GLuint viewElemLengthOverride = 0)
{ {
const char funcName[] = "compressedTexImage3D"; const FuncScope funcScope(*this, "compressedTexImage3D");
const uint8_t funcDims = 3; const uint8_t funcDims = 3;
const TexImageSourceAdapter src(&anySrc, viewElemOffset, viewElemLengthOverride); const TexImageSourceAdapter src(&anySrc, viewElemOffset, viewElemLengthOverride);
CompressedTexImage(funcName, funcDims, target, level, internalFormat, width, CompressedTexImage(funcDims, target, level, internalFormat, width,
height, depth, border, src, Nothing()); height, depth, border, src, Nothing());
} }
@ -144,10 +146,10 @@ public:
GLsizei depth, GLenum unpackFormat, GLsizei depth, GLenum unpackFormat,
GLsizei imageSize, WebGLintptr offset) GLsizei imageSize, WebGLintptr offset)
{ {
const char funcName[] = "compressedTexSubImage3D"; const FuncScope funcScope(*this, "compressedTexSubImage3D");
const uint8_t funcDims = 3; const uint8_t funcDims = 3;
const TexImageSourceAdapter src(&offset, 0, 0); const TexImageSourceAdapter src(&offset, 0, 0);
CompressedTexSubImage(funcName, funcDims, target, level, xOffset, yOffset, CompressedTexSubImage(funcDims, target, level, xOffset, yOffset,
zOffset, width, height, depth, unpackFormat, src, Some(imageSize)); zOffset, width, height, depth, unpackFormat, src, Some(imageSize));
} }
@ -158,10 +160,10 @@ public:
GLuint viewElemOffset = 0, GLuint viewElemOffset = 0,
GLuint viewElemLengthOverride = 0) GLuint viewElemLengthOverride = 0)
{ {
const char funcName[] = "compressedTexSubImage3D"; const FuncScope funcScope(*this, "compressedTexSubImage3D");
const uint8_t funcDims = 3; const uint8_t funcDims = 3;
const TexImageSourceAdapter src(&anySrc, viewElemOffset, viewElemLengthOverride); const TexImageSourceAdapter src(&anySrc, viewElemOffset, viewElemLengthOverride);
CompressedTexSubImage(funcName, funcDims, target, level, xOffset, yOffset, CompressedTexSubImage(funcDims, target, level, xOffset, yOffset,
zOffset, width, height, depth, unpackFormat, src, Nothing()); zOffset, width, height, depth, unpackFormat, src, Nothing());
} }
@ -171,9 +173,9 @@ public:
GLint zOffset, GLint x, GLint y, GLsizei width, GLint zOffset, GLint x, GLint y, GLsizei width,
GLsizei height) GLsizei height)
{ {
const char funcName[] = "copyTexSubImage3D"; const FuncScope funcScope(*this, "copyTexSubImage3D");
const uint8_t funcDims = 3; const uint8_t funcDims = 3;
CopyTexSubImage(funcName, funcDims, target, level, xOffset, yOffset, zOffset, CopyTexSubImage(funcDims, target, level, xOffset, yOffset, zOffset,
x, y, width, height); x, y, width, height);
} }
@ -204,9 +206,9 @@ protected:
GLsizei height, GLsizei depth, GLint border, GLenum unpackFormat, GLsizei height, GLsizei depth, GLint border, GLenum unpackFormat,
GLenum unpackType, const TexImageSource& src) GLenum unpackType, const TexImageSource& src)
{ {
const char funcName[] = "texImage3D"; const FuncScope funcScope(*this, "texImage3D");
const uint8_t funcDims = 3; const uint8_t funcDims = 3;
TexImage(funcName, funcDims, target, level, internalFormat, width, height, depth, TexImage(funcDims, target, level, internalFormat, width, height, depth,
border, unpackFormat, unpackType, src); border, unpackFormat, unpackType, src);
} }
@ -230,10 +232,11 @@ public:
const dom::Nullable<dom::ArrayBufferView>& maybeSrcView, const dom::Nullable<dom::ArrayBufferView>& maybeSrcView,
GLuint srcElemOffset, ErrorResult&) GLuint srcElemOffset, ErrorResult&)
{ {
const FuncScope funcScope(*this, "texSubImage3D");
if (IsContextLost()) if (IsContextLost())
return; return;
if (!ValidateNonNull("texSubImage3D", maybeSrcView)) if (!ValidateNonNull("src", maybeSrcView))
return; return;
const auto& srcView = maybeSrcView.Value(); const auto& srcView = maybeSrcView.Value();
@ -247,9 +250,9 @@ protected:
GLint zOffset, GLsizei width, GLsizei height, GLsizei depth, GLint zOffset, GLsizei width, GLsizei height, GLsizei depth,
GLenum unpackFormat, GLenum unpackType, const TexImageSource& src) GLenum unpackFormat, GLenum unpackType, const TexImageSource& src)
{ {
const char funcName[] = "texSubImage3D"; const FuncScope funcScope(*this, "texSubImage3D");
const uint8_t funcDims = 3; const uint8_t funcDims = 3;
TexSubImage(funcName, funcDims, target, level, xOffset, yOffset, zOffset, width, TexSubImage(funcDims, target, level, xOffset, yOffset, zOffset, width,
height, depth, unpackFormat, unpackType, src); height, depth, unpackFormat, unpackType, src);
} }
@ -265,24 +268,23 @@ public:
void VertexAttribIPointer(GLuint index, GLint size, GLenum type, GLsizei stride, void VertexAttribIPointer(GLuint index, GLint size, GLenum type, GLsizei stride,
WebGLintptr byteOffset) WebGLintptr byteOffset)
{ {
const char funcName[] = "vertexAttribIPointer"; const FuncScope funcScope(*this, "vertexAttribIPointer");
const bool isFuncInt = true; const bool isFuncInt = true;
const bool normalized = false; const bool normalized = false;
VertexAttribAnyPointer(funcName, isFuncInt, index, size, type, normalized, stride, VertexAttribAnyPointer(isFuncInt, index, size, type, normalized, stride,
byteOffset); byteOffset);
} }
//////////////// ////////////////
// GL 3.0 & ES 3.0 // GL 3.0 & ES 3.0
void VertexAttribI4i(GLuint index, GLint x, GLint y, GLint z, GLint w, void VertexAttribI4i(GLuint index, GLint x, GLint y, GLint z, GLint w);
const char* funcName = nullptr); void VertexAttribI4ui(GLuint index, GLuint x, GLuint y, GLuint z, GLuint w);
void VertexAttribI4ui(GLuint index, GLuint x, GLuint y, GLuint z, GLuint w,
const char* funcName = nullptr);
void VertexAttribI4iv(GLuint index, const Int32ListU& list) { void VertexAttribI4iv(GLuint index, const Int32ListU& list) {
const FuncScope funcScope(*this, "VertexAttribI4iv");
const auto& arr = Int32Arr::From(list); const auto& arr = Int32Arr::From(list);
if (!ValidateAttribArraySetter("vertexAttribI4iv", 4, arr.elemCount)) if (!ValidateAttribArraySetter(4, arr.elemCount))
return; return;
const auto& itr = arr.elemBytes; const auto& itr = arr.elemBytes;
@ -290,8 +292,9 @@ public:
} }
void VertexAttribI4uiv(GLuint index, const Uint32ListU& list) { void VertexAttribI4uiv(GLuint index, const Uint32ListU& list) {
const FuncScope funcScope(*this, "vertexAttribI4uiv");
const auto& arr = Uint32Arr::From(list); const auto& arr = Uint32Arr::From(list);
if (!ValidateAttribArraySetter("vertexAttribI4uiv", 4, arr.elemCount)) if (!ValidateAttribArraySetter(4, arr.elemCount))
return; return;
const auto& itr = arr.elemBytes; const auto& itr = arr.elemBytes;
@ -310,16 +313,16 @@ public:
void DrawRangeElements(GLenum mode, GLuint start, GLuint end, GLsizei count, void DrawRangeElements(GLenum mode, GLuint start, GLuint end, GLsizei count,
GLenum type, WebGLintptr byteOffset) GLenum type, WebGLintptr byteOffset)
{ {
const char funcName[] = "drawRangeElements"; const FuncScope funcScope(*this, "drawRangeElements");
if (IsContextLost()) if (IsContextLost())
return; return;
if (end < start) { if (end < start) {
ErrorInvalidValue("%s: end must be >= start.", funcName); ErrorInvalidValue("end must be >= start.");
return; return;
} }
DrawElements(mode, count, type, byteOffset, funcName); DrawElements(mode, count, type, byteOffset);
} }
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
@ -329,7 +332,7 @@ public:
*/ */
private: private:
bool ValidateClearBuffer(const char* funcName, GLenum buffer, GLint drawBuffer, bool ValidateClearBuffer(GLenum buffer, GLint drawBuffer,
size_t availElemCount, GLuint elemOffset, GLenum funcType); size_t availElemCount, GLuint elemOffset, GLenum funcType);
void ClearBufferfv(GLenum buffer, GLint drawBuffer, const Float32Arr& src, void ClearBufferfv(GLenum buffer, GLint drawBuffer, const Float32Arr& src,

Просмотреть файл

@ -19,21 +19,21 @@ WebGL2Context::CopyBufferSubData(GLenum readTarget, GLenum writeTarget,
GLintptr readOffset, GLintptr writeOffset, GLintptr readOffset, GLintptr writeOffset,
GLsizeiptr size) GLsizeiptr size)
{ {
const char funcName[] = "copyBufferSubData"; const FuncScope funcScope(*this, "copyBufferSubData");
if (IsContextLost()) if (IsContextLost())
return; return;
const auto& readBuffer = ValidateBufferSelection(funcName, readTarget); const auto& readBuffer = ValidateBufferSelection(readTarget);
if (!readBuffer) if (!readBuffer)
return; return;
const auto& writeBuffer = ValidateBufferSelection(funcName, writeTarget); const auto& writeBuffer = ValidateBufferSelection(writeTarget);
if (!writeBuffer) if (!writeBuffer)
return; return;
if (!ValidateNonNegative(funcName, "readOffset", readOffset) || if (!ValidateNonNegative("readOffset", readOffset) ||
!ValidateNonNegative(funcName, "writeOffset", writeOffset) || !ValidateNonNegative("writeOffset", writeOffset) ||
!ValidateNonNegative(funcName, "size", size)) !ValidateNonNegative("size", size))
{ {
return; return;
} }
@ -43,7 +43,7 @@ WebGL2Context::CopyBufferSubData(GLenum readTarget, GLenum writeTarget,
{ {
const auto neededBytes = CheckedInt<size_t>(offset) + size; const auto neededBytes = CheckedInt<size_t>(offset) + size;
if (!neededBytes.isValid() || neededBytes.value() > buffer->ByteLength()) { if (!neededBytes.isValid() || neededBytes.value() > buffer->ByteLength()) {
ErrorInvalidValue("%s: Invalid %s range.", funcName, info); ErrorInvalidValue("Invalid %s range.", info);
return false; return false;
} }
return true; return true;
@ -62,9 +62,8 @@ WebGL2Context::CopyBufferSubData(GLenum readTarget, GLenum writeTarget,
const bool separate = (readOffset + size <= writeOffset || const bool separate = (readOffset + size <= writeOffset ||
writeOffset + size <= readOffset); writeOffset + size <= readOffset);
if (!separate) { if (!separate) {
ErrorInvalidValue("%s: ranges [readOffset, readOffset + size) and" ErrorInvalidValue("Ranges [readOffset, readOffset + size) and"
" [writeOffset, writeOffset + size) overlap", " [writeOffset, writeOffset + size) overlap.");
funcName);
return; return;
} }
} }
@ -74,8 +73,7 @@ WebGL2Context::CopyBufferSubData(GLenum readTarget, GLenum writeTarget,
MOZ_ASSERT(readType != WebGLBuffer::Kind::Undefined); MOZ_ASSERT(readType != WebGLBuffer::Kind::Undefined);
MOZ_ASSERT(writeType != WebGLBuffer::Kind::Undefined); MOZ_ASSERT(writeType != WebGLBuffer::Kind::Undefined);
if (writeType != readType) { if (writeType != readType) {
ErrorInvalidOperation("%s: Can't copy %s data to %s data.", ErrorInvalidOperation("Can't copy %s data to %s data.",
funcName,
(readType == WebGLBuffer::Kind::OtherData) ? "other" (readType == WebGLBuffer::Kind::OtherData) ? "other"
: "element", : "element",
(writeType == WebGLBuffer::Kind::OtherData) ? "other" (writeType == WebGLBuffer::Kind::OtherData) ? "other"
@ -95,16 +93,16 @@ WebGL2Context::GetBufferSubData(GLenum target, GLintptr srcByteOffset,
const dom::ArrayBufferView& dstData, GLuint dstElemOffset, const dom::ArrayBufferView& dstData, GLuint dstElemOffset,
GLuint dstElemCountOverride) GLuint dstElemCountOverride)
{ {
const char funcName[] = "getBufferSubData"; const FuncScope funcScope(*this, "getBufferSubData");
if (IsContextLost()) if (IsContextLost())
return; return;
if (!ValidateNonNegative(funcName, "srcByteOffset", srcByteOffset)) if (!ValidateNonNegative("srcByteOffset", srcByteOffset))
return; return;
uint8_t* bytes; uint8_t* bytes;
size_t byteLen; size_t byteLen;
if (!ValidateArrayBufferView(funcName, dstData, dstElemOffset, dstElemCountOverride, if (!ValidateArrayBufferView(dstData, dstElemOffset, dstElemCountOverride,
&bytes, &byteLen)) &bytes, &byteLen))
{ {
return; return;
@ -112,17 +110,17 @@ WebGL2Context::GetBufferSubData(GLenum target, GLintptr srcByteOffset,
//// ////
const auto& buffer = ValidateBufferSelection(funcName, target); const auto& buffer = ValidateBufferSelection(target);
if (!buffer) if (!buffer)
return; return;
if (!buffer->ValidateRange(funcName, srcByteOffset, byteLen)) if (!buffer->ValidateRange(srcByteOffset, byteLen))
return; return;
//// ////
if (!CheckedInt<GLsizeiptr>(byteLen).isValid()) { if (!CheckedInt<GLsizeiptr>(byteLen).isValid()) {
ErrorOutOfMemory("%s: Size too large.", funcName); ErrorOutOfMemory("Size too large.");
return; return;
} }
const GLsizeiptr glByteLen(byteLen); const GLsizeiptr glByteLen(byteLen);
@ -134,16 +132,14 @@ WebGL2Context::GetBufferSubData(GLenum target, GLintptr srcByteOffset,
case LOCAL_GL_STREAM_READ: case LOCAL_GL_STREAM_READ:
case LOCAL_GL_DYNAMIC_READ: case LOCAL_GL_DYNAMIC_READ:
if (mCompletedFenceId < buffer->mLastUpdateFenceId) { if (mCompletedFenceId < buffer->mLastUpdateFenceId) {
GenerateWarning("%s: Reading from a buffer without checking for previous" GenerateWarning("Reading from a buffer without checking for previous"
" command completion likely causes pipeline stalls." " command completion likely causes pipeline stalls."
" Please use FenceSync.", " Please use FenceSync.");
funcName);
} }
break; break;
default: default:
GenerateWarning("%s: Reading from a buffer with usage other than *_READ" GenerateWarning("Reading from a buffer with usage other than *_READ"
" causes pipeline stalls. Copy through a STREAM_READ buffer.", " causes pipeline stalls. Copy through a STREAM_READ buffer.");
funcName);
break; break;
} }

Просмотреть файл

@ -19,6 +19,7 @@ WebGL2Context::BlitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY
GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
GLbitfield mask, GLenum filter) GLbitfield mask, GLenum filter)
{ {
const FuncScope funcScope(*this, "blitFramebuffer");
if (IsContextLost()) if (IsContextLost())
return; return;
@ -26,7 +27,7 @@ WebGL2Context::BlitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY
LOCAL_GL_DEPTH_BUFFER_BIT | LOCAL_GL_DEPTH_BUFFER_BIT |
LOCAL_GL_STENCIL_BUFFER_BIT; LOCAL_GL_STENCIL_BUFFER_BIT;
if ((mask | validBits) != validBits) { if ((mask | validBits) != validBits) {
ErrorInvalidValue("blitFramebuffer: Invalid bit set in mask."); ErrorInvalidValue("Invalid bit set in mask.");
return; return;
} }
@ -35,7 +36,7 @@ WebGL2Context::BlitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY
case LOCAL_GL_LINEAR: case LOCAL_GL_LINEAR:
break; break;
default: default:
ErrorInvalidEnumInfo("blitFramebuffer: Bad `filter`:", filter); ErrorInvalidEnumInfo("filter", filter);
return; return;
} }
@ -50,15 +51,14 @@ WebGL2Context::BlitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY
if (fnLikelyOverflow(srcX0, srcX1) || fnLikelyOverflow(srcY0, srcY1) || if (fnLikelyOverflow(srcX0, srcX1) || fnLikelyOverflow(srcY0, srcY1) ||
fnLikelyOverflow(dstX0, dstX1) || fnLikelyOverflow(dstY0, dstY1)) fnLikelyOverflow(dstX0, dstX1) || fnLikelyOverflow(dstY0, dstY1))
{ {
ErrorInvalidValue("blitFramebuffer: Likely-to-overflow large ranges are" ErrorInvalidValue("Likely-to-overflow large ranges are forbidden.");
" forbidden.");
return; return;
} }
// -- // --
if (!ValidateAndInitFB("blitFramebuffer: READ_FRAMEBUFFER", mBoundReadFramebuffer) || if (!ValidateAndInitFB(mBoundReadFramebuffer) ||
!ValidateAndInitFB("blitFramebuffer: DRAW_FRAMEBUFFER", mBoundDrawFramebuffer)) !ValidateAndInitFB(mBoundDrawFramebuffer))
{ {
return; return;
} }
@ -76,11 +76,11 @@ void
WebGL2Context::FramebufferTextureLayer(GLenum target, GLenum attachment, WebGL2Context::FramebufferTextureLayer(GLenum target, GLenum attachment,
WebGLTexture* texture, GLint level, GLint layer) WebGLTexture* texture, GLint level, GLint layer)
{ {
const char funcName[] = "framebufferTextureLayer"; const FuncScope funcScope(*this, "framebufferTextureLayer");
if (IsContextLost()) if (IsContextLost())
return; return;
if (!ValidateFramebufferTarget(target, funcName)) if (!ValidateFramebufferTarget(target))
return; return;
WebGLFramebuffer* fb; WebGLFramebuffer* fb;
@ -99,9 +99,9 @@ WebGL2Context::FramebufferTextureLayer(GLenum target, GLenum attachment,
} }
if (!fb) if (!fb)
return ErrorInvalidOperation("%s: Cannot modify framebuffer 0.", funcName); return ErrorInvalidOperation("Cannot modify framebuffer 0.");
fb->FramebufferTextureLayer(funcName, attachment, texture, level, layer); fb->FramebufferTextureLayer(attachment, texture, level, layer);
} }
JS::Value JS::Value
@ -118,8 +118,7 @@ WebGL2Context::GetFramebufferAttachmentParameter(JSContext* cx,
//// ////
static bool static bool
ValidateBackbufferAttachmentEnum(WebGLContext* webgl, const char* funcName, ValidateBackbufferAttachmentEnum(WebGLContext* webgl, GLenum attachment)
GLenum attachment)
{ {
switch (attachment) { switch (attachment) {
case LOCAL_GL_COLOR: case LOCAL_GL_COLOR:
@ -128,14 +127,13 @@ ValidateBackbufferAttachmentEnum(WebGLContext* webgl, const char* funcName,
return true; return true;
default: default:
webgl->ErrorInvalidEnum("%s: attachment: invalid enum value 0x%x.", webgl->ErrorInvalidEnumInfo("attachment", attachment);
funcName, attachment);
return false; return false;
} }
} }
static bool static bool
ValidateFramebufferAttachmentEnum(WebGLContext* webgl, const char* funcName, ValidateFramebufferAttachmentEnum(WebGLContext* webgl,
GLenum attachment) GLenum attachment)
{ {
switch (attachment) { switch (attachment) {
@ -146,15 +144,13 @@ ValidateFramebufferAttachmentEnum(WebGLContext* webgl, const char* funcName,
} }
if (attachment < LOCAL_GL_COLOR_ATTACHMENT0) { if (attachment < LOCAL_GL_COLOR_ATTACHMENT0) {
webgl->ErrorInvalidEnum("%s: attachment: invalid enum value 0x%x.", webgl->ErrorInvalidEnumInfo("attachment", attachment);
funcName, attachment);
return false; return false;
} }
if (attachment > webgl->LastColorAttachmentEnum()) { if (attachment > webgl->LastColorAttachmentEnum()) {
// That these errors have different types is ridiculous. // That these errors have different types is ridiculous.
webgl->ErrorInvalidOperation("%s: Too-large LOCAL_GL_COLOR_ATTACHMENTn.", webgl->ErrorInvalidOperation("Too-large LOCAL_GL_COLOR_ATTACHMENTn.");
funcName);
return false; return false;
} }
@ -162,7 +158,7 @@ ValidateFramebufferAttachmentEnum(WebGLContext* webgl, const char* funcName,
} }
bool bool
WebGLContext::ValidateInvalidateFramebuffer(const char* funcName, GLenum target, WebGLContext::ValidateInvalidateFramebuffer(GLenum target,
const dom::Sequence<GLenum>& attachments, const dom::Sequence<GLenum>& attachments,
ErrorResult* const out_rv, ErrorResult* const out_rv,
std::vector<GLenum>* const scopedVector, std::vector<GLenum>* const scopedVector,
@ -172,7 +168,7 @@ WebGLContext::ValidateInvalidateFramebuffer(const char* funcName, GLenum target,
if (IsContextLost()) if (IsContextLost())
return false; return false;
if (!ValidateFramebufferTarget(target, funcName)) if (!ValidateFramebufferTarget(target))
return false; return false;
const WebGLFramebuffer* fb; const WebGLFramebuffer* fb;
@ -192,11 +188,11 @@ WebGLContext::ValidateInvalidateFramebuffer(const char* funcName, GLenum target,
} }
if (fb) { if (fb) {
const auto fbStatus = fb->CheckFramebufferStatus(funcName); const auto fbStatus = fb->CheckFramebufferStatus();
if (fbStatus != LOCAL_GL_FRAMEBUFFER_COMPLETE) if (fbStatus != LOCAL_GL_FRAMEBUFFER_COMPLETE)
return false; // Not an error, but don't run forward to driver either. return false; // Not an error, but don't run forward to driver either.
} else { } else {
if (!EnsureDefaultFB(funcName)) if (!EnsureDefaultFB())
return false; return false;
} }
DoBindFB(fb, target); DoBindFB(fb, target);
@ -206,12 +202,12 @@ WebGLContext::ValidateInvalidateFramebuffer(const char* funcName, GLenum target,
if (fb) { if (fb) {
for (const auto& attachment : attachments) { for (const auto& attachment : attachments) {
if (!ValidateFramebufferAttachmentEnum(this, funcName, attachment)) if (!ValidateFramebufferAttachmentEnum(this, attachment))
return false; return false;
} }
} else { } else {
for (const auto& attachment : attachments) { for (const auto& attachment : attachments) {
if (!ValidateBackbufferAttachmentEnum(this, funcName, attachment)) if (!ValidateBackbufferAttachmentEnum(this, attachment))
return false; return false;
} }
@ -255,12 +251,12 @@ WebGL2Context::InvalidateFramebuffer(GLenum target,
const dom::Sequence<GLenum>& attachments, const dom::Sequence<GLenum>& attachments,
ErrorResult& rv) ErrorResult& rv)
{ {
const char funcName[] = "invalidateSubFramebuffer"; const FuncScope funcScope(*this, "invalidateFramebuffer");
std::vector<GLenum> scopedVector; std::vector<GLenum> scopedVector;
GLsizei glNumAttachments; GLsizei glNumAttachments;
const GLenum* glAttachments; const GLenum* glAttachments;
if (!ValidateInvalidateFramebuffer(funcName, target, attachments, &rv, &scopedVector, if (!ValidateInvalidateFramebuffer(target, attachments, &rv, &scopedVector,
&glNumAttachments, &glAttachments)) &glNumAttachments, &glAttachments))
{ {
return; return;
@ -285,23 +281,23 @@ WebGL2Context::InvalidateSubFramebuffer(GLenum target, const dom::Sequence<GLenu
GLint x, GLint y, GLsizei width, GLsizei height, GLint x, GLint y, GLsizei width, GLsizei height,
ErrorResult& rv) ErrorResult& rv)
{ {
const char funcName[] = "invalidateSubFramebuffer"; const FuncScope funcScope(*this, "invalidateSubFramebuffer");
if (!ValidateNonNegative(funcName, "width", width) ||
!ValidateNonNegative(funcName, "height", height))
{
return;
}
std::vector<GLenum> scopedVector; std::vector<GLenum> scopedVector;
GLsizei glNumAttachments; GLsizei glNumAttachments;
const GLenum* glAttachments; const GLenum* glAttachments;
if (!ValidateInvalidateFramebuffer(funcName, target, attachments, &rv, &scopedVector, if (!ValidateInvalidateFramebuffer(target, attachments, &rv, &scopedVector,
&glNumAttachments, &glAttachments)) &glNumAttachments, &glAttachments))
{ {
return; return;
} }
if (!ValidateNonNegative("width", width) ||
!ValidateNonNegative("height", height))
{
return;
}
//// ////
// Some drivers (like OSX 10.9 GL) just don't support invalidate_framebuffer. // Some drivers (like OSX 10.9 GL) just don't support invalidate_framebuffer.
@ -320,12 +316,12 @@ WebGL2Context::InvalidateSubFramebuffer(GLenum target, const dom::Sequence<GLenu
void void
WebGL2Context::ReadBuffer(GLenum mode) WebGL2Context::ReadBuffer(GLenum mode)
{ {
const char funcName[] = "readBuffer"; const FuncScope funcScope(*this, "readBuffer");
if (IsContextLost()) if (IsContextLost())
return; return;
if (mBoundReadFramebuffer) { if (mBoundReadFramebuffer) {
mBoundReadFramebuffer->ReadBuffer(funcName, mode); mBoundReadFramebuffer->ReadBuffer(mode);
return; return;
} }
@ -335,9 +331,9 @@ WebGL2Context::ReadBuffer(GLenum mode)
{ {
nsCString enumName; nsCString enumName;
EnumName(mode, &enumName); EnumName(mode, &enumName);
ErrorInvalidOperation("%s: If READ_FRAMEBUFFER is null, `mode` must be BACK or" ErrorInvalidOperation("If READ_FRAMEBUFFER is null, `mode` must be BACK or"
" NONE. Was %s.", " NONE. Was %s.",
funcName, enumName.BeginReading()); enumName.BeginReading());
return; return;
} }

Просмотреть файл

@ -11,12 +11,12 @@
namespace mozilla { namespace mozilla {
bool bool
WebGL2Context::ValidateClearBuffer(const char* funcName, GLenum buffer, GLint drawBuffer, WebGL2Context::ValidateClearBuffer(GLenum buffer, GLint drawBuffer,
size_t availElemCount, GLuint elemOffset, size_t availElemCount, GLuint elemOffset,
GLenum funcType) GLenum funcType)
{ {
if (elemOffset > availElemCount) { if (elemOffset > availElemCount) {
ErrorInvalidValue("%s: Offset too big for list.", funcName); ErrorInvalidValue("Offset too big for list.");
return false; return false;
} }
availElemCount -= elemOffset; availElemCount -= elemOffset;
@ -43,31 +43,31 @@ WebGL2Context::ValidateClearBuffer(const char* funcName, GLenum buffer, GLint dr
break; break;
default: default:
ErrorInvalidEnumInfo(funcName, buffer); ErrorInvalidEnumInfo("buffer", buffer);
return false; return false;
} }
if (drawBuffer < 0 || drawBuffer > maxDrawBuffer) { if (drawBuffer < 0 || drawBuffer > maxDrawBuffer) {
ErrorInvalidValue("%s: Invalid drawbuffer %d. This buffer only supports" ErrorInvalidValue("Invalid drawbuffer %d. This buffer only supports"
" `drawbuffer` values between 0 and %u.", " `drawbuffer` values between 0 and %u.",
funcName, drawBuffer, maxDrawBuffer); drawBuffer, maxDrawBuffer);
return false; return false;
} }
if (availElemCount < requiredElements) { if (availElemCount < requiredElements) {
ErrorInvalidValue("%s: Not enough elements. Require %zu. Given %zu.", ErrorInvalidValue("Not enough elements. Require %zu. Given %zu.",
funcName, requiredElements, availElemCount); requiredElements, availElemCount);
return false; return false;
} }
//// ////
if (!BindCurFBForDraw(funcName)) if (!BindCurFBForDraw())
return false; return false;
const auto& fb = mBoundDrawFramebuffer; const auto& fb = mBoundDrawFramebuffer;
if (fb) { if (fb) {
if (!fb->ValidateClearBufferType(funcName, buffer, drawBuffer, funcType)) if (!fb->ValidateClearBufferType(buffer, drawBuffer, funcType))
return false; return false;
} else if (buffer == LOCAL_GL_COLOR) { } else if (buffer == LOCAL_GL_COLOR) {
if (drawBuffer != 0) if (drawBuffer != 0)
@ -77,9 +77,8 @@ WebGL2Context::ValidateClearBuffer(const char* funcName, GLenum buffer, GLint dr
return true; return true;
if (funcType != LOCAL_GL_FLOAT) { if (funcType != LOCAL_GL_FLOAT) {
ErrorInvalidOperation("%s: For default framebuffer, COLOR is always of type" ErrorInvalidOperation("For default framebuffer, COLOR is always of type"
" FLOAT.", " FLOAT.");
funcName);
return false; return false;
} }
} }
@ -93,18 +92,18 @@ void
WebGL2Context::ClearBufferfv(GLenum buffer, GLint drawBuffer, const Float32Arr& src, WebGL2Context::ClearBufferfv(GLenum buffer, GLint drawBuffer, const Float32Arr& src,
GLuint srcElemOffset) GLuint srcElemOffset)
{ {
const char funcName[] = "clearBufferfv"; const FuncScope funcScope(*this, "clearBufferfv");
if (IsContextLost()) if (IsContextLost())
return; return;
if (buffer != LOCAL_GL_COLOR && if (buffer != LOCAL_GL_COLOR &&
buffer != LOCAL_GL_DEPTH) buffer != LOCAL_GL_DEPTH)
{ {
ErrorInvalidEnum("%s: buffer must be COLOR or DEPTH.", funcName); ErrorInvalidEnum("`buffer` must be COLOR or DEPTH.");
return; return;
} }
if (!ValidateClearBuffer(funcName, buffer, drawBuffer, src.elemCount, srcElemOffset, if (!ValidateClearBuffer(buffer, drawBuffer, src.elemCount, srcElemOffset,
LOCAL_GL_FLOAT)) LOCAL_GL_FLOAT))
{ {
return; return;
@ -126,18 +125,18 @@ void
WebGL2Context::ClearBufferiv(GLenum buffer, GLint drawBuffer, const Int32Arr& src, WebGL2Context::ClearBufferiv(GLenum buffer, GLint drawBuffer, const Int32Arr& src,
GLuint srcElemOffset) GLuint srcElemOffset)
{ {
const char funcName[] = "clearBufferiv"; const FuncScope funcScope(*this, "clearBufferiv");
if (IsContextLost()) if (IsContextLost())
return; return;
if (buffer != LOCAL_GL_COLOR && if (buffer != LOCAL_GL_COLOR &&
buffer != LOCAL_GL_STENCIL) buffer != LOCAL_GL_STENCIL)
{ {
ErrorInvalidEnum("%s: buffer must be COLOR or STENCIL.", funcName); ErrorInvalidEnum("`buffer` must be COLOR or STENCIL.");
return; return;
} }
if (!ValidateClearBuffer(funcName, buffer, drawBuffer, src.elemCount, srcElemOffset, if (!ValidateClearBuffer(buffer, drawBuffer, src.elemCount, srcElemOffset,
LOCAL_GL_INT)) LOCAL_GL_INT))
{ {
return; return;
@ -159,14 +158,14 @@ void
WebGL2Context::ClearBufferuiv(GLenum buffer, GLint drawBuffer, const Uint32Arr& src, WebGL2Context::ClearBufferuiv(GLenum buffer, GLint drawBuffer, const Uint32Arr& src,
GLuint srcElemOffset) GLuint srcElemOffset)
{ {
const char funcName[] = "clearBufferuiv"; const FuncScope funcScope(*this, "clearBufferuiv");
if (IsContextLost()) if (IsContextLost())
return; return;
if (buffer != LOCAL_GL_COLOR) if (buffer != LOCAL_GL_COLOR)
return ErrorInvalidEnum("%s: buffer must be COLOR.", funcName); return ErrorInvalidEnum("`buffer` must be COLOR.");
if (!ValidateClearBuffer(funcName, buffer, drawBuffer, src.elemCount, srcElemOffset, if (!ValidateClearBuffer(buffer, drawBuffer, src.elemCount, srcElemOffset,
LOCAL_GL_UNSIGNED_INT)) LOCAL_GL_UNSIGNED_INT))
{ {
return; return;
@ -183,14 +182,14 @@ void
WebGL2Context::ClearBufferfi(GLenum buffer, GLint drawBuffer, GLfloat depth, WebGL2Context::ClearBufferfi(GLenum buffer, GLint drawBuffer, GLfloat depth,
GLint stencil) GLint stencil)
{ {
const char funcName[] = "clearBufferfi"; const FuncScope funcScope(*this, "clearBufferfi");
if (IsContextLost()) if (IsContextLost())
return; return;
if (buffer != LOCAL_GL_DEPTH_STENCIL) if (buffer != LOCAL_GL_DEPTH_STENCIL)
return ErrorInvalidEnum("%s: buffer must be DEPTH_STENCIL.", funcName); return ErrorInvalidEnum("`buffer` must be DEPTH_STENCIL.");
if (!ValidateClearBuffer(funcName, buffer, drawBuffer, 2, 0, 0)) if (!ValidateClearBuffer(buffer, drawBuffer, 2, 0, 0))
return; return;
auto driverDepth = depth; auto driverDepth = depth;

Просмотреть файл

@ -16,10 +16,11 @@ namespace mozilla {
GLint GLint
WebGL2Context::GetFragDataLocation(const WebGLProgram& prog, const nsAString& name) WebGL2Context::GetFragDataLocation(const WebGLProgram& prog, const nsAString& name)
{ {
const FuncScope funcScope(*this, "getFragDataLocation");
if (IsContextLost()) if (IsContextLost())
return -1; return -1;
if (!ValidateObject("getFragDataLocation: program", prog)) if (!ValidateObject("program", prog))
return -1; return -1;
return prog.GetFragDataLocation(name); return prog.GetFragDataLocation(name);

Просмотреть файл

@ -23,7 +23,7 @@ namespace mozilla {
*/ */
WebGLRefPtr<WebGLQuery>* WebGLRefPtr<WebGLQuery>*
WebGLContext::ValidateQuerySlotByTarget(const char* funcName, GLenum target) WebGLContext::ValidateQuerySlotByTarget(GLenum target)
{ {
if (IsWebGL2()) { if (IsWebGL2()) {
switch (target) { switch (target) {
@ -49,7 +49,7 @@ WebGLContext::ValidateQuerySlotByTarget(const char* funcName, GLenum target)
} }
} }
ErrorInvalidEnum("%s: Bad `target`.", funcName); ErrorInvalidEnumInfo("target", target);
return nullptr; return nullptr;
} }
@ -58,12 +58,9 @@ WebGLContext::ValidateQuerySlotByTarget(const char* funcName, GLenum target)
// Query Objects // Query Objects
already_AddRefed<WebGLQuery> already_AddRefed<WebGLQuery>
WebGLContext::CreateQuery(const char* funcName) WebGLContext::CreateQuery()
{ {
if (!funcName) { const FuncScope funcScope(*this, "createQuery");
funcName = "createQuery";
}
if (IsContextLost()) if (IsContextLost())
return nullptr; return nullptr;
@ -72,50 +69,31 @@ WebGLContext::CreateQuery(const char* funcName)
} }
void void
WebGLContext::DeleteQuery(WebGLQuery* query, const char* funcName) WebGLContext::DeleteQuery(WebGLQuery* query)
{ {
if (!funcName) { const FuncScope funcScope(*this, "deleteQuery");
funcName = "deleteQuery"; if (!ValidateDeleteObject(query))
}
if (!ValidateDeleteObject(funcName, query))
return; return;
query->DeleteQuery(); query->DeleteQuery();
} }
bool
WebGLContext::IsQuery(const WebGLQuery* query, const char* funcName)
{
if (!funcName) {
funcName = "isQuery";
}
if (!ValidateIsObject(funcName, query))
return false;
return query->IsQuery();
}
void void
WebGLContext::BeginQuery(GLenum target, WebGLQuery& query, const char* funcName) WebGLContext::BeginQuery(GLenum target, WebGLQuery& query)
{ {
if (!funcName) { const FuncScope funcScope(*this, "beginQuery");
funcName = "beginQuery";
}
if (IsContextLost()) if (IsContextLost())
return; return;
if (!ValidateObject(funcName, query)) if (!ValidateObject("query", query))
return; return;
const auto& slot = ValidateQuerySlotByTarget(funcName, target); const auto& slot = ValidateQuerySlotByTarget(target);
if (!slot) if (!slot)
return; return;
if (*slot) if (*slot)
return ErrorInvalidOperation("%s: Query target already active.", funcName); return ErrorInvalidOperation("Query target already active.");
//// ////
@ -123,33 +101,28 @@ WebGLContext::BeginQuery(GLenum target, WebGLQuery& query, const char* funcName)
} }
void void
WebGLContext::EndQuery(GLenum target, const char* funcName) WebGLContext::EndQuery(GLenum target)
{ {
if (!funcName) { const FuncScope funcScope(*this, "endQuery");
funcName = "endQuery";
}
if (IsContextLost()) if (IsContextLost())
return; return;
const auto& slot = ValidateQuerySlotByTarget(funcName, target); const auto& slot = ValidateQuerySlotByTarget(target);
if (!slot) if (!slot)
return; return;
const auto& query = *slot; const auto& query = *slot;
if (!query) if (!query)
return ErrorInvalidOperation("%s: Query target not active.", funcName); return ErrorInvalidOperation("Query target not active.");
query->EndQuery(); query->EndQuery();
} }
void void
WebGLContext::GetQuery(JSContext* cx, GLenum target, GLenum pname, WebGLContext::GetQuery(JSContext* cx, GLenum target, GLenum pname,
JS::MutableHandleValue retval, const char* funcName) JS::MutableHandleValue retval)
{ {
if (!funcName) { const FuncScope funcScope(*this, "getQuery");
funcName = "getQuery";
}
retval.setNull(); retval.setNull();
if (IsContextLost()) if (IsContextLost())
@ -167,7 +140,7 @@ WebGLContext::GetQuery(JSContext* cx, GLenum target, GLenum pname,
return; return;
} }
const auto& slot = ValidateQuerySlotByTarget(funcName, target); const auto& slot = ValidateQuerySlotByTarget(target);
if (!slot || !*slot) if (!slot || !*slot)
return; return;
@ -188,7 +161,7 @@ WebGLContext::GetQuery(JSContext* cx, GLenum target, GLenum pname,
if (target != LOCAL_GL_TIME_ELAPSED_EXT && if (target != LOCAL_GL_TIME_ELAPSED_EXT &&
target != LOCAL_GL_TIMESTAMP_EXT) target != LOCAL_GL_TIMESTAMP_EXT)
{ {
ErrorInvalidEnum("%s: Bad pname for target.", funcName); ErrorInvalidEnumInfo("target", target);
return; return;
} }
@ -207,22 +180,19 @@ WebGLContext::GetQuery(JSContext* cx, GLenum target, GLenum pname,
break; break;
} }
ErrorInvalidEnum("%s: Bad pname.", funcName); ErrorInvalidEnumInfo("pname", pname);
} }
void void
WebGLContext::GetQueryParameter(JSContext*, const WebGLQuery& query, GLenum pname, WebGLContext::GetQueryParameter(JSContext*, const WebGLQuery& query, GLenum pname,
JS::MutableHandleValue retval, const char* funcName) JS::MutableHandleValue retval)
{ {
if (!funcName) { const FuncScope funcScope(*this, "getQueryParameter");
funcName = "getQueryParameter";
}
retval.setNull(); retval.setNull();
if (IsContextLost()) if (IsContextLost())
return; return;
if (!ValidateObject(funcName, query)) if (!ValidateObject("query", query))
return; return;
query.GetQueryParameter(pname, retval); query.GetQueryParameter(pname, retval);

Просмотреть файл

@ -17,15 +17,14 @@ WebGL2Context::GetInternalformatParameter(JSContext* cx, GLenum target,
JS::MutableHandleValue retval, JS::MutableHandleValue retval,
ErrorResult& out_rv) ErrorResult& out_rv)
{ {
const char funcName[] = "getInternalfomratParameter"; const FuncScope funcScope(*this, "getInternalfomratParameter");
retval.setObjectOrNull(nullptr); retval.setObjectOrNull(nullptr);
if (IsContextLost()) if (IsContextLost())
return; return;
if (target != LOCAL_GL_RENDERBUFFER) { if (target != LOCAL_GL_RENDERBUFFER) {
ErrorInvalidEnum("%s: `target` must be RENDERBUFFER, was: 0x%04x.", funcName, ErrorInvalidEnum("`target` must be RENDERBUFFER.");
target);
return; return;
} }
@ -51,13 +50,13 @@ WebGL2Context::GetInternalformatParameter(JSContext* cx, GLenum target,
const auto usage = mFormatUsage->GetRBUsage(sizedFormat); const auto usage = mFormatUsage->GetRBUsage(sizedFormat);
if (!usage) { if (!usage) {
ErrorInvalidEnum("%s: `internalformat` must be color-, depth-, or stencil-renderable, was: 0x%04x.", ErrorInvalidEnum("`internalformat` must be color-, depth-, or stencil-renderable, was: 0x%04x.",
funcName, internalformat); internalformat);
return; return;
} }
if (pname != LOCAL_GL_SAMPLES) { if (pname != LOCAL_GL_SAMPLES) {
ErrorInvalidEnumInfo("%s: `pname` must be SAMPLES, was 0x%04x.", funcName, pname); ErrorInvalidEnum("`pname` must be SAMPLES.");
return; return;
} }
@ -81,16 +80,4 @@ WebGL2Context::GetInternalformatParameter(JSContext* cx, GLenum target,
retval.setObjectOrNull(obj); retval.setObjectOrNull(obj);
} }
void
WebGL2Context::RenderbufferStorageMultisample(GLenum target, GLsizei samples,
GLenum internalFormat,
GLsizei width, GLsizei height)
{
const char funcName[] = "renderbufferStorageMultisample";
if (IsContextLost())
return;
RenderbufferStorage_base(funcName, target, samples, internalFormat, width, height);
}
} // namespace mozilla } // namespace mozilla

Просмотреть файл

@ -12,6 +12,7 @@ namespace mozilla {
already_AddRefed<WebGLSampler> already_AddRefed<WebGLSampler>
WebGL2Context::CreateSampler() WebGL2Context::CreateSampler()
{ {
const FuncScope funcScope(*this, "createSampler");
if (IsContextLost()) if (IsContextLost())
return nullptr; return nullptr;
@ -22,7 +23,8 @@ WebGL2Context::CreateSampler()
void void
WebGL2Context::DeleteSampler(WebGLSampler* sampler) WebGL2Context::DeleteSampler(WebGLSampler* sampler)
{ {
if (!ValidateDeleteObject("deleteSampler", sampler)) const FuncScope funcScope(*this, "deleteSampler");
if (!ValidateDeleteObject(sampler))
return; return;
for (uint32_t n = 0; n < mGLMaxTextureUnits; n++) { for (uint32_t n = 0; n < mGLMaxTextureUnits; n++) {
@ -37,25 +39,27 @@ WebGL2Context::DeleteSampler(WebGLSampler* sampler)
} }
bool bool
WebGL2Context::IsSampler(const WebGLSampler* sampler) WebGL2Context::IsSampler(const WebGLSampler* const obj)
{ {
if (!ValidateIsObject("isSampler", sampler)) const FuncScope funcScope(*this, "isSampler");
if (!ValidateIsObject(obj))
return false; return false;
return gl->fIsSampler(sampler->mGLName); return gl->fIsSampler(obj->mGLName);
} }
void void
WebGL2Context::BindSampler(GLuint unit, WebGLSampler* sampler) WebGL2Context::BindSampler(GLuint unit, WebGLSampler* sampler)
{ {
const FuncScope funcScope(*this, "bindSampler");
if (IsContextLost()) if (IsContextLost())
return; return;
if (sampler && !ValidateObject("bindSampler", *sampler)) if (sampler && !ValidateObject("sampler", *sampler))
return; return;
if (unit >= mGLMaxTextureUnits) if (unit >= mGLMaxTextureUnits)
return ErrorInvalidValue("bindSampler: unit must be < %u", mGLMaxTextureUnits); return ErrorInvalidValue("unit must be < %u", mGLMaxTextureUnits);
//// ////
@ -68,40 +72,40 @@ WebGL2Context::BindSampler(GLuint unit, WebGLSampler* sampler)
void void
WebGL2Context::SamplerParameteri(WebGLSampler& sampler, GLenum pname, GLint param) WebGL2Context::SamplerParameteri(WebGLSampler& sampler, GLenum pname, GLint param)
{ {
const char funcName[] = "samplerParameteri"; const FuncScope funcScope(*this, "samplerParameteri");
if (IsContextLost()) if (IsContextLost())
return; return;
if (!ValidateObject(funcName, sampler)) if (!ValidateObject("sampler", sampler))
return; return;
sampler.SamplerParameter(funcName, pname, FloatOrInt(param)); sampler.SamplerParameter(pname, FloatOrInt(param));
} }
void void
WebGL2Context::SamplerParameterf(WebGLSampler& sampler, GLenum pname, GLfloat param) WebGL2Context::SamplerParameterf(WebGLSampler& sampler, GLenum pname, GLfloat param)
{ {
const char funcName[] = "samplerParameterf"; const FuncScope funcScope(*this, "samplerParameterf");
if (IsContextLost()) if (IsContextLost())
return; return;
if (!ValidateObject(funcName, sampler)) if (!ValidateObject("sampler", sampler))
return; return;
sampler.SamplerParameter(funcName, pname, FloatOrInt(param)); sampler.SamplerParameter(pname, FloatOrInt(param));
} }
void void
WebGL2Context::GetSamplerParameter(JSContext*, const WebGLSampler& sampler, GLenum pname, WebGL2Context::GetSamplerParameter(JSContext*, const WebGLSampler& sampler, GLenum pname,
JS::MutableHandleValue retval) JS::MutableHandleValue retval)
{ {
const char funcName[] = "getSamplerParameter"; const FuncScope funcScope(*this, "getSamplerParameter");
retval.setNull(); retval.setNull();
if (IsContextLost()) if (IsContextLost())
return; return;
if (!ValidateObject(funcName, sampler)) if (!ValidateObject("sampler", sampler))
return; return;
//// ////
@ -131,7 +135,7 @@ WebGL2Context::GetSamplerParameter(JSContext*, const WebGLSampler& sampler, GLen
return; return;
default: default:
ErrorInvalidEnumArg(funcName, "pname", pname); ErrorInvalidEnumInfo("pname", pname);
return; return;
} }
} }

Просмотреть файл

@ -19,6 +19,7 @@ namespace mozilla {
JS::Value JS::Value
WebGL2Context::GetParameter(JSContext* cx, GLenum pname, ErrorResult& rv) WebGL2Context::GetParameter(JSContext* cx, GLenum pname, ErrorResult& rv)
{ {
const FuncScope funcScope(*this, "getParameter");
// The following cases are handled in WebGLContext::GetParameter(): // The following cases are handled in WebGLContext::GetParameter():
// case LOCAL_GL_MAX_COLOR_ATTACHMENTS: // case LOCAL_GL_MAX_COLOR_ATTACHMENTS:
// case LOCAL_GL_MAX_DRAW_BUFFERS: // case LOCAL_GL_MAX_DRAW_BUFFERS:

Просмотреть файл

@ -16,16 +16,17 @@ namespace mozilla {
already_AddRefed<WebGLSync> already_AddRefed<WebGLSync>
WebGL2Context::FenceSync(GLenum condition, GLbitfield flags) WebGL2Context::FenceSync(GLenum condition, GLbitfield flags)
{ {
const FuncScope funcScope(*this, "fenceSync");
if (IsContextLost()) if (IsContextLost())
return nullptr; return nullptr;
if (condition != LOCAL_GL_SYNC_GPU_COMMANDS_COMPLETE) { if (condition != LOCAL_GL_SYNC_GPU_COMMANDS_COMPLETE) {
ErrorInvalidEnum("fenceSync: condition must be SYNC_GPU_COMMANDS_COMPLETE"); ErrorInvalidEnum("condition must be SYNC_GPU_COMMANDS_COMPLETE");
return nullptr; return nullptr;
} }
if (flags != 0) { if (flags != 0) {
ErrorInvalidValue("fenceSync: flags must be 0"); ErrorInvalidValue("flags must be 0");
return nullptr; return nullptr;
} }
@ -38,18 +39,17 @@ WebGL2Context::FenceSync(GLenum condition, GLbitfield flags)
} }
bool bool
WebGL2Context::IsSync(const WebGLSync* sync) WebGL2Context::IsSync(const WebGLSync* const sync)
{ {
if (!ValidateIsObject("isSync", sync)) const FuncScope funcScope(*this, "isSync");
return false; return ValidateIsObject(sync);
return true;
} }
void void
WebGL2Context::DeleteSync(WebGLSync* sync) WebGL2Context::DeleteSync(WebGLSync* sync)
{ {
if (!ValidateDeleteObject("deleteSync", sync)) const FuncScope funcScope(*this, "deleteSync");
if (!ValidateDeleteObject(sync))
return; return;
sync->RequestDelete(); sync->RequestDelete();
@ -58,20 +58,20 @@ WebGL2Context::DeleteSync(WebGLSync* sync)
GLenum GLenum
WebGL2Context::ClientWaitSync(const WebGLSync& sync, GLbitfield flags, GLuint64 timeout) WebGL2Context::ClientWaitSync(const WebGLSync& sync, GLbitfield flags, GLuint64 timeout)
{ {
const char funcName[] = "clientWaitSync"; const FuncScope funcScope(*this, "clientWaitSync");
if (IsContextLost()) if (IsContextLost())
return LOCAL_GL_WAIT_FAILED; return LOCAL_GL_WAIT_FAILED;
if (!ValidateObject(funcName, sync)) if (!ValidateObject("sync", sync))
return LOCAL_GL_WAIT_FAILED; return LOCAL_GL_WAIT_FAILED;
if (flags != 0 && flags != LOCAL_GL_SYNC_FLUSH_COMMANDS_BIT) { if (flags != 0 && flags != LOCAL_GL_SYNC_FLUSH_COMMANDS_BIT) {
ErrorInvalidValue("%s: `flags` must be SYNC_FLUSH_COMMANDS_BIT or 0.", funcName); ErrorInvalidValue("`flags` must be SYNC_FLUSH_COMMANDS_BIT or 0.");
return LOCAL_GL_WAIT_FAILED; return LOCAL_GL_WAIT_FAILED;
} }
if (timeout > kMaxClientWaitSyncTimeoutNS) { if (timeout > kMaxClientWaitSyncTimeoutNS) {
ErrorInvalidOperation("%s: `timeout` must not exceed %s nanoseconds.", funcName, ErrorInvalidOperation("`timeout` must not exceed %s nanoseconds.",
"MAX_CLIENT_WAIT_TIMEOUT_WEBGL"); "MAX_CLIENT_WAIT_TIMEOUT_WEBGL");
return LOCAL_GL_WAIT_FAILED; return LOCAL_GL_WAIT_FAILED;
} }
@ -80,9 +80,8 @@ WebGL2Context::ClientWaitSync(const WebGLSync& sync, GLbitfield flags, GLuint64
gfxPrefs::WebGLImmediateQueries()); gfxPrefs::WebGLImmediateQueries());
if (!canBeAvailable) { if (!canBeAvailable) {
if (timeout) { if (timeout) {
GenerateWarning("%s: Sync object not yet queryable. Please wait for the event" GenerateWarning("Sync object not yet queryable. Please wait for the event"
" loop.", " loop.");
funcName);
} }
return LOCAL_GL_WAIT_FAILED; return LOCAL_GL_WAIT_FAILED;
} }
@ -101,20 +100,20 @@ WebGL2Context::ClientWaitSync(const WebGLSync& sync, GLbitfield flags, GLuint64
void void
WebGL2Context::WaitSync(const WebGLSync& sync, GLbitfield flags, GLint64 timeout) WebGL2Context::WaitSync(const WebGLSync& sync, GLbitfield flags, GLint64 timeout)
{ {
const char funcName[] = "waitSync"; const FuncScope funcScope(*this, "waitSync");
if (IsContextLost()) if (IsContextLost())
return; return;
if (!ValidateObject(funcName, sync)) if (!ValidateObject("sync", sync))
return; return;
if (flags != 0) { if (flags != 0) {
ErrorInvalidValue("%s: `flags` must be 0.", funcName); ErrorInvalidValue("`flags` must be 0.");
return; return;
} }
if (timeout != -1) { if (timeout != -1) {
ErrorInvalidValue("%s: `timeout` must be TIMEOUT_IGNORED.", funcName); ErrorInvalidValue("`timeout` must be TIMEOUT_IGNORED.");
return; return;
} }
@ -125,12 +124,12 @@ void
WebGL2Context::GetSyncParameter(JSContext*, const WebGLSync& sync, GLenum pname, WebGL2Context::GetSyncParameter(JSContext*, const WebGLSync& sync, GLenum pname,
JS::MutableHandleValue retval) JS::MutableHandleValue retval)
{ {
const char funcName[] = "getSyncParameter"; const FuncScope funcScope(*this, "getSyncParameter");
retval.setNull(); retval.setNull();
if (IsContextLost()) if (IsContextLost())
return; return;
if (!ValidateObject(funcName, sync)) if (!ValidateObject("sync", sync))
return; return;
//// ////
@ -160,7 +159,7 @@ WebGL2Context::GetSyncParameter(JSContext*, const WebGLSync& sync, GLenum pname,
return; return;
default: default:
ErrorInvalidEnum("%s: Invalid pname 0x%04x", funcName, pname); ErrorInvalidEnumInfo("pname", pname);
return; return;
} }
} }

Просмотреть файл

@ -11,16 +11,18 @@
namespace mozilla { namespace mozilla {
void void
WebGL2Context::TexStorage(const char* funcName, uint8_t funcDims, GLenum rawTarget, WebGL2Context::TexStorage(uint8_t funcDims, GLenum rawTarget,
GLsizei levels, GLenum internalFormat, GLsizei width, GLsizei levels, GLenum internalFormat, GLsizei width,
GLsizei height, GLsizei depth) GLsizei height, GLsizei depth)
{ {
const FuncScope funcScope(*this, "texStorage");
TexTarget target; TexTarget target;
WebGLTexture* tex; WebGLTexture* tex;
if (!ValidateTexTarget(this, funcName, funcDims, rawTarget, &target, &tex)) if (!ValidateTexTarget(this, funcDims, rawTarget, &target, &tex))
return; return;
tex->TexStorage(funcName, target, levels, internalFormat, width, height, depth); tex->TexStorage(target, levels, internalFormat, width, height, depth);
} }
//////////////////// ////////////////////

Просмотреть файл

@ -17,6 +17,7 @@ namespace mozilla {
already_AddRefed<WebGLTransformFeedback> already_AddRefed<WebGLTransformFeedback>
WebGL2Context::CreateTransformFeedback() WebGL2Context::CreateTransformFeedback()
{ {
const FuncScope funcScope(*this, "createTransformFeedback");
if (IsContextLost()) if (IsContextLost())
return nullptr; return nullptr;
@ -30,12 +31,12 @@ WebGL2Context::CreateTransformFeedback()
void void
WebGL2Context::DeleteTransformFeedback(WebGLTransformFeedback* tf) WebGL2Context::DeleteTransformFeedback(WebGLTransformFeedback* tf)
{ {
const char funcName[] = "deleteTransformFeedback"; const FuncScope funcScope(*this, "deleteTransformFeedback");
if (!ValidateDeleteObject(funcName, tf)) if (!ValidateDeleteObject(tf))
return; return;
if (tf->mIsActive) { if (tf->mIsActive) {
ErrorInvalidOperation("%s: Cannot delete active transform feedbacks.", funcName); ErrorInvalidOperation("Cannot delete active transform feedbacks.");
return; return;
} }
@ -47,33 +48,33 @@ WebGL2Context::DeleteTransformFeedback(WebGLTransformFeedback* tf)
} }
bool bool
WebGL2Context::IsTransformFeedback(const WebGLTransformFeedback* tf) WebGL2Context::IsTransformFeedback(const WebGLTransformFeedback* const obj)
{ {
if (!ValidateIsObject("isTransformFeedback", tf)) const FuncScope funcScope(*this, "isTransformFeedback");
if (!ValidateIsObject(obj))
return false; return false;
return gl->fIsTransformFeedback(tf->mGLName); return gl->fIsTransformFeedback(obj->mGLName);
} }
void void
WebGL2Context::BindTransformFeedback(GLenum target, WebGLTransformFeedback* tf) WebGL2Context::BindTransformFeedback(GLenum target, WebGLTransformFeedback* tf)
{ {
const char funcName[] = "bindTransformFeedback"; const FuncScope funcScope(*this, "bindTransformFeedback");
if (IsContextLost()) if (IsContextLost())
return; return;
if (target != LOCAL_GL_TRANSFORM_FEEDBACK) if (target != LOCAL_GL_TRANSFORM_FEEDBACK)
return ErrorInvalidEnum("%s: `target` must be TRANSFORM_FEEDBACK.", funcName); return ErrorInvalidEnum("`target` must be TRANSFORM_FEEDBACK.");
if (tf && !ValidateObject(funcName, *tf)) if (tf && !ValidateObject("tf", *tf))
return; return;
if (mBoundTransformFeedback->mIsActive && if (mBoundTransformFeedback->mIsActive &&
!mBoundTransformFeedback->mIsPaused) !mBoundTransformFeedback->mIsPaused)
{ {
ErrorInvalidOperation("%s: Currently bound transform feedback is active and not" ErrorInvalidOperation("Currently bound transform feedback is active and not"
" paused.", " paused.");
funcName);
return; return;
} }
@ -95,6 +96,7 @@ WebGL2Context::BindTransformFeedback(GLenum target, WebGLTransformFeedback* tf)
void void
WebGL2Context::BeginTransformFeedback(GLenum primMode) WebGL2Context::BeginTransformFeedback(GLenum primMode)
{ {
const FuncScope funcScope(*this, "beginTransformFeedback");
if (IsContextLost()) if (IsContextLost())
return; return;
@ -104,6 +106,7 @@ WebGL2Context::BeginTransformFeedback(GLenum primMode)
void void
WebGL2Context::EndTransformFeedback() WebGL2Context::EndTransformFeedback()
{ {
const FuncScope funcScope(*this, "endTransformFeedback");
if (IsContextLost()) if (IsContextLost())
return; return;
@ -113,6 +116,7 @@ WebGL2Context::EndTransformFeedback()
void void
WebGL2Context::PauseTransformFeedback() WebGL2Context::PauseTransformFeedback()
{ {
const FuncScope funcScope(*this, "pauseTransformFeedback");
if (IsContextLost()) if (IsContextLost())
return; return;
@ -122,6 +126,7 @@ WebGL2Context::PauseTransformFeedback()
void void
WebGL2Context::ResumeTransformFeedback() WebGL2Context::ResumeTransformFeedback()
{ {
const FuncScope funcScope(*this, "resumeTransformFeedback");
if (IsContextLost()) if (IsContextLost())
return; return;
@ -133,10 +138,11 @@ WebGL2Context::TransformFeedbackVaryings(WebGLProgram& program,
const dom::Sequence<nsString>& varyings, const dom::Sequence<nsString>& varyings,
GLenum bufferMode) GLenum bufferMode)
{ {
const FuncScope funcScope(*this, "transformFeedbackVaryings");
if (IsContextLost()) if (IsContextLost())
return; return;
if (!ValidateObject("transformFeedbackVaryings: program", program)) if (!ValidateObject("program", program))
return; return;
program.TransformFeedbackVaryings(varyings, bufferMode); program.TransformFeedbackVaryings(varyings, bufferMode);
@ -145,10 +151,11 @@ WebGL2Context::TransformFeedbackVaryings(WebGLProgram& program,
already_AddRefed<WebGLActiveInfo> already_AddRefed<WebGLActiveInfo>
WebGL2Context::GetTransformFeedbackVarying(const WebGLProgram& program, GLuint index) WebGL2Context::GetTransformFeedbackVarying(const WebGLProgram& program, GLuint index)
{ {
const FuncScope funcScope(*this, "getTransformFeedbackVarying");
if (IsContextLost()) if (IsContextLost())
return nullptr; return nullptr;
if (!ValidateObject("getTransformFeedbackVarying: program", program)) if (!ValidateObject("program", program))
return nullptr; return nullptr;
return program.GetTransformFeedbackVarying(index); return program.GetTransformFeedbackVarying(index);

Просмотреть файл

@ -23,7 +23,8 @@ namespace mozilla {
void void
WebGLContext::Uniform1ui(WebGLUniformLocation* loc, GLuint v0) WebGLContext::Uniform1ui(WebGLUniformLocation* loc, GLuint v0)
{ {
if (!ValidateUniformSetter(loc, 1, LOCAL_GL_UNSIGNED_INT, "uniform1ui")) const FuncScope funcScope(*this, "uniform1ui");
if (!ValidateUniformSetter(loc, 1, LOCAL_GL_UNSIGNED_INT))
return; return;
gl->fUniform1ui(loc->mLoc, v0); gl->fUniform1ui(loc->mLoc, v0);
@ -32,7 +33,8 @@ WebGLContext::Uniform1ui(WebGLUniformLocation* loc, GLuint v0)
void void
WebGLContext::Uniform2ui(WebGLUniformLocation* loc, GLuint v0, GLuint v1) WebGLContext::Uniform2ui(WebGLUniformLocation* loc, GLuint v0, GLuint v1)
{ {
if (!ValidateUniformSetter(loc, 2, LOCAL_GL_UNSIGNED_INT, "uniform2ui")) const FuncScope funcScope(*this, "uniform2ui");
if (!ValidateUniformSetter(loc, 2, LOCAL_GL_UNSIGNED_INT))
return; return;
gl->fUniform2ui(loc->mLoc, v0, v1); gl->fUniform2ui(loc->mLoc, v0, v1);
@ -41,7 +43,8 @@ WebGLContext::Uniform2ui(WebGLUniformLocation* loc, GLuint v0, GLuint v1)
void void
WebGLContext::Uniform3ui(WebGLUniformLocation* loc, GLuint v0, GLuint v1, GLuint v2) WebGLContext::Uniform3ui(WebGLUniformLocation* loc, GLuint v0, GLuint v1, GLuint v2)
{ {
if (!ValidateUniformSetter(loc, 3, LOCAL_GL_UNSIGNED_INT, "uniform3ui")) const FuncScope funcScope(*this, "uniform3ui");
if (!ValidateUniformSetter(loc, 3, LOCAL_GL_UNSIGNED_INT))
return; return;
gl->fUniform3ui(loc->mLoc, v0, v1, v2); gl->fUniform3ui(loc->mLoc, v0, v1, v2);
@ -51,7 +54,8 @@ void
WebGLContext::Uniform4ui(WebGLUniformLocation* loc, GLuint v0, GLuint v1, GLuint v2, WebGLContext::Uniform4ui(WebGLUniformLocation* loc, GLuint v0, GLuint v1, GLuint v2,
GLuint v3) GLuint v3)
{ {
if (!ValidateUniformSetter(loc, 4, LOCAL_GL_UNSIGNED_INT, "uniform4ui")) const FuncScope funcScope(*this, "uniform4ui");
if (!ValidateUniformSetter(loc, 4, LOCAL_GL_UNSIGNED_INT))
return; return;
gl->fUniform4ui(loc->mLoc, v0, v1, v2, v3); gl->fUniform4ui(loc->mLoc, v0, v1, v2, v3);
@ -64,7 +68,7 @@ void
WebGL2Context::GetIndexedParameter(JSContext* cx, GLenum target, GLuint index, WebGL2Context::GetIndexedParameter(JSContext* cx, GLenum target, GLuint index,
JS::MutableHandleValue retval, ErrorResult& out_error) JS::MutableHandleValue retval, ErrorResult& out_error)
{ {
const char funcName[] = "getIndexedParameter"; const FuncScope funcScope(*this, "getIndexedParameter");
retval.set(JS::NullValue()); retval.set(JS::NullValue());
if (IsContextLost()) if (IsContextLost())
return; return;
@ -84,12 +88,12 @@ WebGL2Context::GetIndexedParameter(JSContext* cx, GLenum target, GLuint index,
break; break;
default: default:
ErrorInvalidEnumInfo("getIndexedParameter: target", target); ErrorInvalidEnumInfo("target", target);
return; return;
} }
if (index >= bindings->size()) { if (index >= bindings->size()) {
ErrorInvalidValue("%s: `index` must be < %s.", funcName, ErrorInvalidValue("`index` must be < %s.",
"MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS"); "MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS");
return; return;
} }
@ -124,11 +128,12 @@ WebGL2Context::GetUniformIndices(const WebGLProgram& program,
const dom::Sequence<nsString>& uniformNames, const dom::Sequence<nsString>& uniformNames,
dom::Nullable< nsTArray<GLuint> >& retval) dom::Nullable< nsTArray<GLuint> >& retval)
{ {
const FuncScope funcScope(*this, "getUniformIndices");
retval.SetNull(); retval.SetNull();
if (IsContextLost()) if (IsContextLost())
return; return;
if (!ValidateObject("getUniformIndices: program", program)) if (!ValidateObject("program", program))
return; return;
if (!uniformNames.Length()) if (!uniformNames.Length())
@ -137,9 +142,16 @@ WebGL2Context::GetUniformIndices(const WebGLProgram& program,
program.GetUniformIndices(uniformNames, retval); program.GetUniformIndices(uniformNames, retval);
} }
static bool void
ValidateUniformEnum(WebGLContext* webgl, GLenum pname, const char* info) WebGL2Context::GetActiveUniforms(JSContext* cx, const WebGLProgram& program,
const dom::Sequence<GLuint>& uniformIndices,
GLenum pname, JS::MutableHandleValue retval)
{ {
const FuncScope funcScope(*this, "getActiveUniforms");
retval.setNull();
if (IsContextLost())
return;
switch (pname) { switch (pname) {
case LOCAL_GL_UNIFORM_TYPE: case LOCAL_GL_UNIFORM_TYPE:
case LOCAL_GL_UNIFORM_SIZE: case LOCAL_GL_UNIFORM_SIZE:
@ -148,39 +160,25 @@ ValidateUniformEnum(WebGLContext* webgl, GLenum pname, const char* info)
case LOCAL_GL_UNIFORM_ARRAY_STRIDE: case LOCAL_GL_UNIFORM_ARRAY_STRIDE:
case LOCAL_GL_UNIFORM_MATRIX_STRIDE: case LOCAL_GL_UNIFORM_MATRIX_STRIDE:
case LOCAL_GL_UNIFORM_IS_ROW_MAJOR: case LOCAL_GL_UNIFORM_IS_ROW_MAJOR:
return true; break;
default: default:
webgl->ErrorInvalidEnumArg(info, "pname", pname); ErrorInvalidEnumInfo("pname", pname);
return false; return;
} }
}
void if (!ValidateObject("program", program))
WebGL2Context::GetActiveUniforms(JSContext* cx, const WebGLProgram& program,
const dom::Sequence<GLuint>& uniformIndices,
GLenum pname, JS::MutableHandleValue retval)
{
const char funcName[] = "getActiveUniforms";
retval.setNull();
if (IsContextLost())
return;
if (!ValidateUniformEnum(this, pname, funcName))
return;
if (!ValidateObject("getActiveUniforms: program", program))
return; return;
if (!program.IsLinked()) { if (!program.IsLinked()) {
ErrorInvalidOperation("%s: `program` must be linked.", funcName); ErrorInvalidOperation("`program` must be linked.");
return; return;
} }
const auto& numActiveUniforms = program.LinkInfo()->uniforms.size(); const auto& numActiveUniforms = program.LinkInfo()->uniforms.size();
for (const auto& curIndex : uniformIndices) { for (const auto& curIndex : uniformIndices) {
if (curIndex >= numActiveUniforms) { if (curIndex >= numActiveUniforms) {
ErrorInvalidValue("%s: Too-large active uniform index queried.", funcName); ErrorInvalidValue("Too-large active uniform index queried.");
return; return;
} }
} }
@ -190,7 +188,7 @@ WebGL2Context::GetActiveUniforms(JSContext* cx, const WebGLProgram& program,
JS::Rooted<JSObject*> array(cx, JS_NewArrayObject(cx, count)); JS::Rooted<JSObject*> array(cx, JS_NewArrayObject(cx, count));
UniquePtr<GLint[]> samples(new GLint[count]); UniquePtr<GLint[]> samples(new GLint[count]);
if (!array || !samples) { if (!array || !samples) {
ErrorOutOfMemory("%s: Failed to allocate buffers.", funcName); ErrorOutOfMemory("Failed to allocate buffers.");
return; return;
} }
retval.setObject(*array); retval.setObject(*array);
@ -230,10 +228,11 @@ GLuint
WebGL2Context::GetUniformBlockIndex(const WebGLProgram& program, WebGL2Context::GetUniformBlockIndex(const WebGLProgram& program,
const nsAString& uniformBlockName) const nsAString& uniformBlockName)
{ {
const FuncScope funcScope(*this, "getUniformBlockIndex");
if (IsContextLost()) if (IsContextLost())
return 0; return 0;
if (!ValidateObject("getUniformBlockIndex: program", program)) if (!ValidateObject("program", program))
return 0; return 0;
return program.GetUniformBlockIndex(uniformBlockName); return program.GetUniformBlockIndex(uniformBlockName);
@ -245,11 +244,12 @@ WebGL2Context::GetActiveUniformBlockParameter(JSContext* cx, const WebGLProgram&
JS::MutableHandleValue out_retval, JS::MutableHandleValue out_retval,
ErrorResult& out_error) ErrorResult& out_error)
{ {
const FuncScope funcScope(*this, "getActiveUniformBlockParameter");
out_retval.setNull(); out_retval.setNull();
if (IsContextLost()) if (IsContextLost())
return; return;
if (!ValidateObject("getActiveUniformBlockParameter: program", program)) if (!ValidateObject("program", program))
return; return;
switch(pname) { switch(pname) {
@ -267,18 +267,19 @@ WebGL2Context::GetActiveUniformBlockParameter(JSContext* cx, const WebGLProgram&
return; return;
} }
ErrorInvalidEnumInfo("getActiveUniformBlockParameter: parameter", pname); ErrorInvalidEnumInfo("parameter", pname);
} }
void void
WebGL2Context::GetActiveUniformBlockName(const WebGLProgram& program, WebGL2Context::GetActiveUniformBlockName(const WebGLProgram& program,
GLuint uniformBlockIndex, nsAString& retval) GLuint uniformBlockIndex, nsAString& retval)
{ {
const FuncScope funcScope(*this, "getActiveUniformBlockName");
retval.SetIsVoid(true); retval.SetIsVoid(true);
if (IsContextLost()) if (IsContextLost())
return; return;
if (!ValidateObject("getActiveUniformBlockName: program", program)) if (!ValidateObject("program", program))
return; return;
program.GetActiveUniformBlockName(uniformBlockIndex, retval); program.GetActiveUniformBlockName(uniformBlockIndex, retval);
@ -288,10 +289,11 @@ void
WebGL2Context::UniformBlockBinding(WebGLProgram& program, GLuint uniformBlockIndex, WebGL2Context::UniformBlockBinding(WebGLProgram& program, GLuint uniformBlockIndex,
GLuint uniformBlockBinding) GLuint uniformBlockBinding)
{ {
const FuncScope funcScope(*this, "uniformBlockBinding");
if (IsContextLost()) if (IsContextLost())
return; return;
if (!ValidateObject("uniformBlockBinding: program", program)) if (!ValidateObject("program", program))
return; return;
program.UniformBlockBinding(uniformBlockIndex, uniformBlockBinding); program.UniformBlockBinding(uniformBlockIndex, uniformBlockBinding);

Просмотреть файл

@ -70,7 +70,7 @@ WebGLBuffer::Delete()
//////////////////////////////////////// ////////////////////////////////////////
static bool static bool
ValidateBufferUsageEnum(WebGLContext* webgl, const char* funcName, GLenum usage) ValidateBufferUsageEnum(WebGLContext* webgl, GLenum usage)
{ {
switch (usage) { switch (usage) {
case LOCAL_GL_STREAM_DRAW: case LOCAL_GL_STREAM_DRAW:
@ -92,21 +92,19 @@ ValidateBufferUsageEnum(WebGLContext* webgl, const char* funcName, GLenum usage)
break; break;
} }
webgl->ErrorInvalidEnum("%s: Invalid `usage`: 0x%04x", funcName, usage); webgl->ErrorInvalidEnumInfo("usage", usage);
return false; return false;
} }
void void
WebGLBuffer::BufferData(GLenum target, size_t size, const void* data, GLenum usage) WebGLBuffer::BufferData(GLenum target, size_t size, const void* data, GLenum usage)
{ {
const char funcName[] = "bufferData";
// Careful: data.Length() could conceivably be any uint32_t, but GLsizeiptr // Careful: data.Length() could conceivably be any uint32_t, but GLsizeiptr
// is like intptr_t. // is like intptr_t.
if (!CheckedInt<GLsizeiptr>(size).isValid()) if (!CheckedInt<GLsizeiptr>(size).isValid())
return mContext->ErrorOutOfMemory("%s: bad size", funcName); return mContext->ErrorOutOfMemory("bad size");
if (!ValidateBufferUsageEnum(mContext, funcName, usage)) if (!ValidateBufferUsageEnum(mContext, usage))
return; return;
#ifdef XP_MACOSX #ifdef XP_MACOSX
@ -114,7 +112,7 @@ WebGLBuffer::BufferData(GLenum target, size_t size, const void* data, GLenum usa
if (mContext->gl->WorkAroundDriverBugs() && if (mContext->gl->WorkAroundDriverBugs() &&
size > INT32_MAX) size > INT32_MAX)
{ {
mContext->ErrorOutOfMemory("%s: Allocation size too large.", funcName); mContext->ErrorOutOfMemory("Allocation size too large.");
return; return;
} }
#endif #endif
@ -127,7 +125,7 @@ WebGLBuffer::BufferData(GLenum target, size_t size, const void* data, GLenum usa
{ {
newIndexCache = malloc(size); newIndexCache = malloc(size);
if (!newIndexCache) { if (!newIndexCache) {
mContext->ErrorOutOfMemory("%s: Failed to alloc index cache.", funcName); mContext->ErrorOutOfMemory("Failed to alloc index cache.");
return; return;
} }
memcpy(newIndexCache.get(), data, size); memcpy(newIndexCache.get(), data, size);
@ -145,7 +143,7 @@ WebGLBuffer::BufferData(GLenum target, size_t size, const void* data, GLenum usa
if (error) { if (error) {
MOZ_ASSERT(error == LOCAL_GL_OUT_OF_MEMORY); MOZ_ASSERT(error == LOCAL_GL_OUT_OF_MEMORY);
mContext->ErrorOutOfMemory("%s: Error from driver: 0x%04x", funcName, error); mContext->ErrorOutOfMemory("Error from driver: 0x%04x", error);
return; return;
} }
} else { } else {
@ -174,13 +172,11 @@ void
WebGLBuffer::BufferSubData(GLenum target, size_t dstByteOffset, size_t dataLen, WebGLBuffer::BufferSubData(GLenum target, size_t dstByteOffset, size_t dataLen,
const void* data) const const void* data) const
{ {
const char funcName[] = "bufferSubData"; if (!ValidateRange(dstByteOffset, dataLen))
if (!ValidateRange(funcName, dstByteOffset, dataLen))
return; return;
if (!CheckedInt<GLintptr>(dataLen).isValid()) if (!CheckedInt<GLintptr>(dataLen).isValid())
return mContext->ErrorOutOfMemory("%s: Size too large.", funcName); return mContext->ErrorOutOfMemory("Size too large.");
//// ////
@ -204,18 +200,17 @@ WebGLBuffer::BufferSubData(GLenum target, size_t dstByteOffset, size_t dataLen,
} }
bool bool
WebGLBuffer::ValidateRange(const char* funcName, size_t byteOffset, size_t byteLen) const WebGLBuffer::ValidateRange(size_t byteOffset, size_t byteLen) const
{ {
auto availLength = mByteLength; auto availLength = mByteLength;
if (byteOffset > availLength) { if (byteOffset > availLength) {
mContext->ErrorInvalidValue("%s: Offset passes the end of the buffer.", funcName); mContext->ErrorInvalidValue("Offset passes the end of the buffer.");
return false; return false;
} }
availLength -= byteOffset; availLength -= byteOffset;
if (byteLen > availLength) { if (byteLen > availLength) {
mContext->ErrorInvalidValue("%s: Offset+size passes the end of the buffer.", mContext->ErrorInvalidValue("Offset+size passes the end of the buffer.");
funcName);
return false; return false;
} }
@ -361,7 +356,7 @@ WebGLBuffer::GetIndexedFetchMaxVert(const GLenum type, const uint64_t byteOffset
//// ////
bool bool
WebGLBuffer::ValidateCanBindToTarget(const char* funcName, GLenum target) WebGLBuffer::ValidateCanBindToTarget(GLenum target)
{ {
/* https://www.khronos.org/registry/webgl/specs/latest/2.0/#5.1 /* https://www.khronos.org/registry/webgl/specs/latest/2.0/#5.1
* *
@ -408,7 +403,7 @@ WebGLBuffer::ValidateCanBindToTarget(const char* funcName, GLenum target)
const auto dataType = (mContent == WebGLBuffer::Kind::OtherData) ? "other" const auto dataType = (mContent == WebGLBuffer::Kind::OtherData) ? "other"
: "element"; : "element";
mContext->ErrorInvalidOperation("%s: Buffer already contains %s data.", funcName, mContext->ErrorInvalidOperation("Buffer already contains %s data.",
dataType); dataType);
return false; return false;
} }

Просмотреть файл

@ -47,7 +47,7 @@ public:
Maybe<uint32_t> GetIndexedFetchMaxVert(GLenum type, uint64_t byteOffset, Maybe<uint32_t> GetIndexedFetchMaxVert(GLenum type, uint64_t byteOffset,
uint32_t indexCount) const; uint32_t indexCount) const;
bool ValidateRange(const char* funcName, size_t byteOffset, size_t byteLen) const; bool ValidateRange(size_t byteOffset, size_t byteLen) const;
WebGLContext* GetParentObject() const { WebGLContext* GetParentObject() const {
return mContext; return mContext;
@ -55,7 +55,7 @@ public:
virtual JSObject* WrapObject(JSContext* cx, JS::Handle<JSObject*> givenProto) override; virtual JSObject* WrapObject(JSContext* cx, JS::Handle<JSObject*> givenProto) override;
bool ValidateCanBindToTarget(const char* funcName, GLenum target); bool ValidateCanBindToTarget(GLenum target);
void BufferData(GLenum target, size_t size, const void* data, GLenum usage); void BufferData(GLenum target, size_t size, const void* data, GLenum usage);
void BufferSubData(GLenum target, size_t dstByteOffset, size_t dataLen, void BufferSubData(GLenum target, size_t dstByteOffset, size_t dataLen,
const void* data) const; const void* data) const;

Просмотреть файл

@ -165,7 +165,6 @@ WebGLContext::WebGLContext()
mAllowContextRestore = true; mAllowContextRestore = true;
mLastLossWasSimulated = false; mLastLossWasSimulated = false;
mContextStatus = ContextNotLost;
mLoseContextOnMemoryPressure = false; mLoseContextOnMemoryPressure = false;
mCanLoseContextInForeground = true; mCanLoseContextInForeground = true;
mRestoreWhenVisible = false; mRestoreWhenVisible = false;
@ -329,9 +328,8 @@ WebGLContext::Invalidate()
void void
WebGLContext::OnVisibilityChange() WebGLContext::OnVisibilityChange()
{ {
if (!IsContextLost()) { if (gl) // Context not lost.
return; return;
}
if (!mRestoreWhenVisible || mLastLossWasSimulated) { if (!mRestoreWhenVisible || mLastLossWasSimulated) {
return; return;
@ -524,7 +522,7 @@ WebGLContext::CreateAndInitGL(bool forceEnabled,
switch (mOptions.powerPreference) { switch (mOptions.powerPreference) {
case dom::WebGLPowerPreference::Low_power: case dom::WebGLPowerPreference::Low_power:
break; break;
// Eventually add a heuristic, but for now default to high-performance. // Eventually add a heuristic, but for now default to high-performance.
// We can even make it dynamic by holding on to a ForceDiscreteGPUHelperCGL iff // We can even make it dynamic by holding on to a ForceDiscreteGPUHelperCGL iff
// we decide it's a high-performance application: // we decide it's a high-performance application:
@ -661,7 +659,7 @@ WebGLContext::CreateAndInitGL(bool forceEnabled,
// Fallback for resizes: // Fallback for resizes:
bool bool
WebGLContext::EnsureDefaultFB(const char* const funcName) WebGLContext::EnsureDefaultFB()
{ {
if (mDefaultFB) { if (mDefaultFB) {
MOZ_ASSERT(mDefaultFB->mSize == mRequestedSize); MOZ_ASSERT(mDefaultFB->mSize == mRequestedSize);
@ -698,7 +696,7 @@ WebGLContext::EnsureDefaultFB(const char* const funcName)
} }
if (!mDefaultFB) { if (!mDefaultFB) {
GenerateWarning("%s: Backbuffer resize failed. Losing context.", funcName); GenerateWarning("Backbuffer resize failed. Losing context.");
ForceLoseContext(); ForceLoseContext();
return false; return false;
} }
@ -747,6 +745,9 @@ WebGLContext::ThrowEvent_WebGLContextCreationError(const nsACString& text)
NS_IMETHODIMP NS_IMETHODIMP
WebGLContext::SetDimensions(int32_t signedWidth, int32_t signedHeight) WebGLContext::SetDimensions(int32_t signedWidth, int32_t signedHeight)
{ {
const FuncScope funcScope(*this, "<SetDimensions>");
(void)IsContextLost(); // We handle this ourselves.
if (signedWidth < 0 || signedHeight < 0) { if (signedWidth < 0 || signedHeight < 0) {
if (!gl) { if (!gl) {
Telemetry::Accumulate(Telemetry::CANVAS_WEBGL_FAILURE_ID, Telemetry::Accumulate(Telemetry::CANVAS_WEBGL_FAILURE_ID,
@ -923,7 +924,7 @@ WebGLContext::SetDimensions(int32_t signedWidth, int32_t signedHeight)
MOZ_ASSERT(!mDefaultFB); MOZ_ASSERT(!mDefaultFB);
mRequestedSize = {width, height}; mRequestedSize = {width, height};
if (!EnsureDefaultFB("context initialization")) { if (!EnsureDefaultFB()) {
MOZ_ASSERT(!gl); MOZ_ASSERT(!gl);
failureId = NS_LITERAL_CSTRING("FEATURE_FAILURE_WEBGL_BACKBUFFER"); failureId = NS_LITERAL_CSTRING("FEATURE_FAILURE_WEBGL_BACKBUFFER");
@ -1041,7 +1042,7 @@ WebGLContext::LoseOldestWebGLContextIfLimitExceeded()
if (contexts[i] == this) if (contexts[i] == this)
continue; continue;
if (contexts[i]->IsContextLost()) if (!contexts[i]->gl)
continue; continue;
if (!contexts[i]->GetCanvas()) { if (!contexts[i]->GetCanvas()) {
@ -1231,6 +1232,7 @@ bool
WebGLContext::InitializeCanvasRenderer(nsDisplayListBuilder* aBuilder, WebGLContext::InitializeCanvasRenderer(nsDisplayListBuilder* aBuilder,
CanvasRenderer* aRenderer) CanvasRenderer* aRenderer)
{ {
const FuncScope funcScope(*this, "<InitializeCanvasRenderer>");
if (IsContextLost()) if (IsContextLost())
return false; return false;
@ -1255,7 +1257,7 @@ WebGLContext::InitializeCanvasRenderer(nsDisplayListBuilder* aBuilder,
} }
data.mGLContext = gl; data.mGLContext = gl;
data.mSize = DrawingBufferSize("InitializeCanvasRenderer"); data.mSize = DrawingBufferSize();
data.mHasAlpha = mOptions.alpha; data.mHasAlpha = mOptions.alpha;
data.mIsGLAlphaPremult = IsPremultAlpha() || !data.mHasAlpha; data.mIsGLAlphaPremult = IsPremultAlpha() || !data.mHasAlpha;
@ -1316,6 +1318,7 @@ void
WebGLContext::GetContextAttributes(dom::Nullable<dom::WebGLContextAttributes>& retval) WebGLContext::GetContextAttributes(dom::Nullable<dom::WebGLContextAttributes>& retval)
{ {
retval.SetNull(); retval.SetNull();
const FuncScope funcScope(*this, "getContextAttributes");
if (IsContextLost()) if (IsContextLost())
return; return;
@ -1459,13 +1462,14 @@ WebGLContext::BlitBackbufferToCurDriverFB() const
bool bool
WebGLContext::PresentScreenBuffer() WebGLContext::PresentScreenBuffer()
{ {
const FuncScope funcScope(*this, "<PresentScreenBuffer>");
if (IsContextLost()) if (IsContextLost())
return false; return false;
if (!mShouldPresent) if (!mShouldPresent)
return false; return false;
if (!ValidateAndInitFB("Present", nullptr)) if (!ValidateAndInitFB(nullptr))
return false; return false;
const auto& screen = gl->Screen(); const auto& screen = gl->Screen();
@ -1530,16 +1534,14 @@ WebGLContext::EndComposition()
} }
void void
WebGLContext::DummyReadFramebufferOperation(const char* funcName) WebGLContext::DummyReadFramebufferOperation()
{ {
if (!mBoundReadFramebuffer) if (!mBoundReadFramebuffer)
return; // Infallible. return; // Infallible.
const auto status = mBoundReadFramebuffer->CheckFramebufferStatus(funcName); const auto status = mBoundReadFramebuffer->CheckFramebufferStatus();
if (status != LOCAL_GL_FRAMEBUFFER_COMPLETE) { if (status != LOCAL_GL_FRAMEBUFFER_COMPLETE) {
ErrorInvalidFramebufferOperation("%s: Framebuffer must be complete.", ErrorInvalidFramebufferOperation("Framebuffer must be complete.");
funcName);
} }
} }
@ -1675,7 +1677,7 @@ WebGLContext::UpdateContextLossStatus()
// this timer event. In this case, there's nothing to do here, just don't crash. // this timer event. In this case, there's nothing to do here, just don't crash.
return; return;
} }
if (mContextStatus == ContextNotLost) { if (mContextStatus == ContextStatus::NotLost) {
// We don't know that we're lost, but we might be, so we need to // We don't know that we're lost, but we might be, so we need to
// check. If we're guilty, don't allow restores, though. // check. If we're guilty, don't allow restores, though.
@ -1693,7 +1695,7 @@ WebGLContext::UpdateContextLossStatus()
// Fall through. // Fall through.
} }
if (mContextStatus == ContextLostAwaitingEvent) { if (mContextStatus == ContextStatus::LostAwaitingEvent) {
// The context has been lost and we haven't yet triggered the // The context has been lost and we haven't yet triggered the
// callback, so do that now. // callback, so do that now.
const auto kEventName = NS_LITERAL_STRING("webglcontextlost"); const auto kEventName = NS_LITERAL_STRING("webglcontextlost");
@ -1720,7 +1722,7 @@ WebGLContext::UpdateContextLossStatus()
} }
// We sent the callback, so we're just 'regular lost' now. // We sent the callback, so we're just 'regular lost' now.
mContextStatus = ContextLost; mContextStatus = ContextStatus::Lost;
// If we're told to use the default handler, it means the script // If we're told to use the default handler, it means the script
// didn't bother to handle the event. In this case, we shouldn't // didn't bother to handle the event. In this case, we shouldn't
// auto-restore the context. // auto-restore the context.
@ -1730,7 +1732,7 @@ WebGLContext::UpdateContextLossStatus()
// Fall through. // Fall through.
} }
if (mContextStatus == ContextLost) { if (mContextStatus == ContextStatus::Lost) {
// Context is lost, and we've already sent the callback. We // Context is lost, and we've already sent the callback. We
// should try to restore the context if we're both allowed to, // should try to restore the context if we're both allowed to,
// and supposed to. // and supposed to.
@ -1752,13 +1754,13 @@ WebGLContext::UpdateContextLossStatus()
return; return;
} }
if (mContextStatus == ContextLostAwaitingRestore) { if (mContextStatus == ContextStatus::LostAwaitingRestore) {
// Context is lost, but we should try to restore it. // Context is lost, but we should try to restore it.
if (!mAllowContextRestore) { if (!mAllowContextRestore) {
// We might decide this after thinking we'd be OK restoring // We might decide this after thinking we'd be OK restoring
// the context, so downgrade. // the context, so downgrade.
mContextStatus = ContextLost; mContextStatus = ContextStatus::Lost;
return; return;
} }
@ -1769,7 +1771,7 @@ WebGLContext::UpdateContextLossStatus()
} }
// Revival! // Revival!
mContextStatus = ContextNotLost; mContextStatus = ContextStatus::NotLost;
if (mCanvasElement) { if (mCanvasElement) {
nsContentUtils::DispatchTrustedEvent( nsContentUtils::DispatchTrustedEvent(
@ -1796,8 +1798,8 @@ void
WebGLContext::ForceLoseContext(bool simulateLosing) WebGLContext::ForceLoseContext(bool simulateLosing)
{ {
printf_stderr("WebGL(%p)::ForceLoseContext\n", this); printf_stderr("WebGL(%p)::ForceLoseContext\n", this);
MOZ_ASSERT(!IsContextLost()); MOZ_ASSERT(gl);
mContextStatus = ContextLostAwaitingEvent; mContextStatus = ContextStatus::LostAwaitingEvent;
mContextLostErrorSet = false; mContextLostErrorSet = false;
// Burn it all! // Burn it all!
@ -1812,7 +1814,7 @@ void
WebGLContext::ForceRestoreContext() WebGLContext::ForceRestoreContext()
{ {
printf_stderr("WebGL(%p)::ForceRestoreContext\n", this); printf_stderr("WebGL(%p)::ForceRestoreContext\n", this);
mContextStatus = ContextLostAwaitingRestore; mContextStatus = ContextStatus::LostAwaitingRestore;
mAllowContextRestore = true; // Hey, you did say 'force'. mAllowContextRestore = true; // Hey, you did say 'force'.
// Queue up a task, since we know the status changed. // Queue up a task, since we know the status changed.
@ -1822,10 +1824,11 @@ WebGLContext::ForceRestoreContext()
already_AddRefed<mozilla::gfx::SourceSurface> already_AddRefed<mozilla::gfx::SourceSurface>
WebGLContext::GetSurfaceSnapshot(gfxAlphaType* const out_alphaType) WebGLContext::GetSurfaceSnapshot(gfxAlphaType* const out_alphaType)
{ {
if (!gl) const FuncScope funcScope(*this, "<GetSurfaceSnapshot>");
if (IsContextLost())
return nullptr; return nullptr;
if (!BindDefaultFBForRead("GetSurfaceSnapshot")) if (!BindDefaultFBForRead())
return nullptr; return nullptr;
const auto surfFormat = mOptions.alpha ? SurfaceFormat::B8G8R8A8 const auto surfFormat = mOptions.alpha ? SurfaceFormat::B8G8R8A8
@ -1882,26 +1885,25 @@ WebGLContext::DidRefresh()
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
gfx::IntSize gfx::IntSize
WebGLContext::DrawingBufferSize(const char* const funcName) WebGLContext::DrawingBufferSize()
{ {
const gfx::IntSize zeros{0, 0}; const gfx::IntSize zeros{0, 0};
if (IsContextLost()) if (IsContextLost())
return zeros; return zeros;
if (!EnsureDefaultFB(funcName)) if (!EnsureDefaultFB())
return zeros; return zeros;
return mDefaultFB->mSize; return mDefaultFB->mSize;
} }
bool bool
WebGLContext::ValidateAndInitFB(const char* const funcName, WebGLContext::ValidateAndInitFB(const WebGLFramebuffer* const fb)
const WebGLFramebuffer* const fb)
{ {
if (fb) if (fb)
return fb->ValidateAndInitAttachments(funcName); return fb->ValidateAndInitAttachments();
if (!EnsureDefaultFB(funcName)) if (!EnsureDefaultFB())
return false; return false;
if (mDefaultFB_IsInvalid) { if (mDefaultFB_IsInvalid) {
@ -1924,10 +1926,10 @@ WebGLContext::DoBindFB(const WebGLFramebuffer* const fb, const GLenum target) co
} }
bool bool
WebGLContext::BindCurFBForDraw(const char* const funcName) WebGLContext::BindCurFBForDraw()
{ {
const auto& fb = mBoundDrawFramebuffer; const auto& fb = mBoundDrawFramebuffer;
if (!ValidateAndInitFB(funcName, fb)) if (!ValidateAndInitFB(fb))
return false; return false;
DoBindFB(fb); DoBindFB(fb);
@ -1935,30 +1937,27 @@ WebGLContext::BindCurFBForDraw(const char* const funcName)
} }
bool bool
WebGLContext::BindCurFBForColorRead(const char* const funcName, WebGLContext::BindCurFBForColorRead(const webgl::FormatUsageInfo** const out_format,
const webgl::FormatUsageInfo** const out_format,
uint32_t* const out_width, uint32_t* const out_width,
uint32_t* const out_height) uint32_t* const out_height)
{ {
const auto& fb = mBoundReadFramebuffer; const auto& fb = mBoundReadFramebuffer;
if (fb) { if (fb) {
if (!ValidateAndInitFB(funcName, fb)) if (!ValidateAndInitFB(fb))
return false; return false;
if (!fb->ValidateForColorRead(funcName, out_format, out_width, out_height)) if (!fb->ValidateForColorRead(out_format, out_width, out_height))
return false; return false;
gl->fBindFramebuffer(LOCAL_GL_FRAMEBUFFER, fb->mGLName); gl->fBindFramebuffer(LOCAL_GL_FRAMEBUFFER, fb->mGLName);
return true; return true;
} }
if (!BindDefaultFBForRead(funcName)) if (!BindDefaultFBForRead())
return false; return false;
if (mDefaultFB_ReadBuffer == LOCAL_GL_NONE) { if (mDefaultFB_ReadBuffer == LOCAL_GL_NONE) {
ErrorInvalidOperation("%s: Can't read from backbuffer when readBuffer mode is" ErrorInvalidOperation("Can't read from backbuffer when readBuffer mode is NONE.");
" NONE.",
funcName);
return false; return false;
} }
@ -1974,9 +1973,9 @@ WebGLContext::BindCurFBForColorRead(const char* const funcName,
} }
bool bool
WebGLContext::BindDefaultFBForRead(const char* const funcName) WebGLContext::BindDefaultFBForRead()
{ {
if (!ValidateAndInitFB(funcName, nullptr)) if (!ValidateAndInitFB(nullptr))
return false; return false;
if (!mDefaultFB->mSamples) { if (!mDefaultFB->mSamples) {
@ -1987,7 +1986,7 @@ WebGLContext::BindDefaultFBForRead(const char* const funcName)
if (!mResolvedDefaultFB) { if (!mResolvedDefaultFB) {
mResolvedDefaultFB = MozFramebuffer::Create(gl, mDefaultFB->mSize, 0, false); mResolvedDefaultFB = MozFramebuffer::Create(gl, mDefaultFB->mSize, 0, false);
if (!mResolvedDefaultFB) { if (!mResolvedDefaultFB) {
gfxCriticalNote << funcName << ": Failed to create mResolvedDefaultFB."; gfxCriticalNote << FuncName() << ": Failed to create mResolvedDefaultFB.";
return false; return false;
} }
} }
@ -2299,9 +2298,8 @@ WebGLContext::GetUnpackSize(bool isFunc3D, uint32_t width, uint32_t height,
already_AddRefed<layers::SharedSurfaceTextureClient> already_AddRefed<layers::SharedSurfaceTextureClient>
WebGLContext::GetVRFrame() WebGLContext::GetVRFrame()
{ {
if (IsContextLost()) { if (!gl)
ForceRestoreContext(); return nullptr;
}
int frameId = gfx::impl::VRDisplayExternal::sPushIndex; int frameId = gfx::impl::VRDisplayExternal::sPushIndex;
static int lastFrameId = -1; static int lastFrameId = -1;
@ -2317,7 +2315,7 @@ WebGLContext::GetVRFrame()
EndComposition(); EndComposition();
} }
if (IsContextLost()) { if (!gl) {
return nullptr; return nullptr;
} }
@ -2334,7 +2332,7 @@ WebGLContext::GetVRFrame()
/** /**
* Make sure that the WebGL buffer is committed to the attached SurfaceTexture on Android. * Make sure that the WebGL buffer is committed to the attached SurfaceTexture on Android.
*/ */
if (!ignoreFrame && !IsContextLost()) { if (!ignoreFrame) {
sharedSurface->Surf()->ProducerAcquire(); sharedSurface->Surf()->ProducerAcquire();
sharedSurface->Surf()->Commit(); sharedSurface->Surf()->Commit();
sharedSurface->Surf()->ProducerRelease(); sharedSurface->Surf()->ProducerRelease();
@ -2354,7 +2352,7 @@ WebGLContext::GetVRFrame()
BeginComposition(); BeginComposition();
EndComposition(); EndComposition();
if (IsContextLost()) if (!gl)
return nullptr; return nullptr;
gl::GLScreenBuffer* screen = gl->Screen(); gl::GLScreenBuffer* screen = gl->Screen();
@ -2383,8 +2381,7 @@ SizeOfViewElem(const dom::ArrayBufferView& view)
} }
bool bool
WebGLContext::ValidateArrayBufferView(const char* funcName, WebGLContext::ValidateArrayBufferView(const dom::ArrayBufferView& view, GLuint elemOffset,
const dom::ArrayBufferView& view, GLuint elemOffset,
GLuint elemCountOverride, uint8_t** const out_bytes, GLuint elemCountOverride, uint8_t** const out_bytes,
size_t* const out_byteLen) size_t* const out_byteLen)
{ {
@ -2396,14 +2393,14 @@ WebGLContext::ValidateArrayBufferView(const char* funcName,
size_t elemCount = byteLen / elemSize; size_t elemCount = byteLen / elemSize;
if (elemOffset > elemCount) { if (elemOffset > elemCount) {
ErrorInvalidValue("%s: Invalid offset into ArrayBufferView.", funcName); ErrorInvalidValue("Invalid offset into ArrayBufferView.");
return false; return false;
} }
elemCount -= elemOffset; elemCount -= elemOffset;
if (elemCountOverride) { if (elemCountOverride) {
if (elemCountOverride > elemCount) { if (elemCountOverride > elemCount) {
ErrorInvalidValue("%s: Invalid sub-length for ArrayBufferView.", funcName); ErrorInvalidValue("Invalid sub-length for ArrayBufferView.");
return false; return false;
} }
elemCount = elemCountOverride; elemCount = elemCountOverride;
@ -2430,6 +2427,90 @@ WebGLContext::UpdateMaxDrawBuffers()
// -- // --
const char*
WebGLContext::FuncName() const
{
const char* ret;
if (MOZ_LIKELY( mFuncScope )) {
ret = mFuncScope->mFuncName;
} else {
MOZ_ASSERT(false);
ret = "<funcName unknown>";
}
return ret;
}
// -
WebGLContext::FuncScope::FuncScope(const WebGLContext& webgl, const char* const funcName)
: mWebGL(webgl)
, mFuncName(bool(mWebGL.mFuncScope) ? nullptr : funcName)
{
if (MOZ_UNLIKELY( !mFuncName )) {
#ifdef DEBUG
mStillNeedsToCheckContextLost = false;
#endif
return;
}
mWebGL.mFuncScope = this;
}
WebGLContext::FuncScope::~FuncScope()
{
if (MOZ_UNLIKELY( !mFuncName ))
return;
MOZ_ASSERT(!mStillNeedsToCheckContextLost);
mWebGL.mFuncScope = nullptr;
}
bool
WebGLContext::IsContextLost() const
{
if (MOZ_LIKELY( mFuncScope )) {
mFuncScope->OnCheckContextLost();
}
return mContextStatus != ContextStatus::NotLost;
}
// --
bool
WebGLContext::ValidateIsObject(const WebGLDeletableObject* const object) const
{
if (IsContextLost())
return false;
if (!object)
return false;
if (!object->IsCompatibleWithContext(this))
return false;
return !object->IsDeleted();
}
bool
WebGLContext::ValidateDeleteObject(const WebGLDeletableObject* const object)
{
if (IsContextLost())
return false;
if (!object)
return false;
if (!ValidateObjectAllowDeleted("obj", *object))
return false;
if (object->IsDeleteRequested())
return false;
return true;
}
// --
webgl::AvailabilityRunnable* webgl::AvailabilityRunnable*
WebGLContext::EnsureAvailabilityRunnable() WebGLContext::EnsureAvailabilityRunnable()
{ {

Просмотреть файл

@ -305,7 +305,7 @@ class WebGLContext
friend struct webgl::UniformBlockInfo; friend struct webgl::UniformBlockInfo;
friend const webgl::CachedDrawFetchLimits* friend const webgl::CachedDrawFetchLimits*
ValidateDraw(WebGLContext*, const char*, GLenum, uint32_t); ValidateDraw(WebGLContext*, GLenum, uint32_t);
enum { enum {
UNPACK_FLIP_Y_WEBGL = 0x9240, UNPACK_FLIP_Y_WEBGL = 0x9240,
@ -327,6 +327,11 @@ class WebGLContext
uint64_t mNextFenceId = 1; uint64_t mNextFenceId = 1;
uint64_t mCompletedFenceId = 0; uint64_t mCompletedFenceId = 0;
public:
class FuncScope;
private:
mutable FuncScope* mFuncScope = nullptr;
public: public:
WebGLContext(); WebGLContext();
@ -345,8 +350,8 @@ public:
virtual void OnMemoryPressure() override; virtual void OnMemoryPressure() override;
// nsICanvasRenderingContextInternal // nsICanvasRenderingContextInternal
virtual int32_t GetWidth() override { return DrawingBufferWidth("get width"); } virtual int32_t GetWidth() override { return DrawingBufferWidth(); }
virtual int32_t GetHeight() override { return DrawingBufferHeight("get height"); } virtual int32_t GetHeight() override { return DrawingBufferHeight(); }
NS_IMETHOD SetDimensions(int32_t width, int32_t height) override; NS_IMETHOD SetDimensions(int32_t width, int32_t height) override;
NS_IMETHOD InitializeWithDrawTarget(nsIDocShell*, NS_IMETHOD InitializeWithDrawTarget(nsIDocShell*,
@ -389,6 +394,31 @@ public:
return NS_ERROR_NOT_IMPLEMENTED; return NS_ERROR_NOT_IMPLEMENTED;
} }
// -
const auto& CurFuncScope() const { return *mFuncScope; }
const char* FuncName() const;
class FuncScope final {
public:
const WebGLContext& mWebGL;
const char* const mFuncName;
private:
#ifdef DEBUG
mutable bool mStillNeedsToCheckContextLost = true;
#endif
public:
FuncScope(const WebGLContext& webgl, const char* funcName);
~FuncScope();
void OnCheckContextLost() const {
#ifdef DEBUG
mStillNeedsToCheckContextLost = false;
#endif
}
};
void SynthesizeGLError(GLenum err) const; void SynthesizeGLError(GLenum err) const;
void SynthesizeGLError(GLenum err, const char* fmt, ...) const MOZ_FORMAT_PRINTF(3, 4); void SynthesizeGLError(GLenum err, const char* fmt, ...) const MOZ_FORMAT_PRINTF(3, 4);
@ -397,12 +427,10 @@ public:
void ErrorInvalidValue(const char* fmt = 0, ...) const MOZ_FORMAT_PRINTF(2, 3); void ErrorInvalidValue(const char* fmt = 0, ...) const MOZ_FORMAT_PRINTF(2, 3);
void ErrorInvalidFramebufferOperation(const char* fmt = 0, ...) const MOZ_FORMAT_PRINTF(2, 3); void ErrorInvalidFramebufferOperation(const char* fmt = 0, ...) const MOZ_FORMAT_PRINTF(2, 3);
void ErrorInvalidEnumInfo(const char* info, GLenum enumValue) const; void ErrorInvalidEnumInfo(const char* info, GLenum enumValue) const;
void ErrorInvalidEnumInfo(const char* info, const char* funcName,
GLenum enumValue) const;
void ErrorOutOfMemory(const char* fmt = 0, ...) const MOZ_FORMAT_PRINTF(2, 3); void ErrorOutOfMemory(const char* fmt = 0, ...) const MOZ_FORMAT_PRINTF(2, 3);
void ErrorImplementationBug(const char* fmt = 0, ...) const MOZ_FORMAT_PRINTF(2, 3); void ErrorImplementationBug(const char* fmt = 0, ...) const MOZ_FORMAT_PRINTF(2, 3);
void ErrorInvalidEnumArg(const char* funcName, const char* argName, GLenum val) const; void ErrorInvalidEnumArg(const char* argName, GLenum val) const;
static const char* ErrorName(GLenum error); static const char* ErrorName(GLenum error);
@ -414,7 +442,7 @@ public:
*/ */
static void EnumName(GLenum val, nsCString* out_name); static void EnumName(GLenum val, nsCString* out_name);
void DummyReadFramebufferOperation(const char* funcName); void DummyReadFramebufferOperation();
WebGLTexture* ActiveBoundTextureForTarget(const TexTarget texTarget) const { WebGLTexture* ActiveBoundTextureForTarget(const TexTarget texTarget) const {
switch (texTarget.get()) { switch (texTarget.get()) {
@ -504,13 +532,15 @@ public:
void Commit(); void Commit();
void GetCanvas(dom::Nullable<dom::OwningHTMLCanvasElementOrOffscreenCanvas>& retval); void GetCanvas(dom::Nullable<dom::OwningHTMLCanvasElementOrOffscreenCanvas>& retval);
private: private:
gfx::IntSize DrawingBufferSize(const char* funcName); gfx::IntSize DrawingBufferSize();
public: public:
GLsizei DrawingBufferWidth(const char* const funcName = "drawingBufferWidth") { GLsizei DrawingBufferWidth() {
return DrawingBufferSize(funcName).width; const FuncScope funcScope(*this, "drawingBufferWidth");
return DrawingBufferSize().width;
} }
GLsizei DrawingBufferHeight(const char* const funcName = "drawingBufferHeight") { GLsizei DrawingBufferHeight() {
return DrawingBufferSize(funcName).height; const FuncScope funcScope(*this, "drawingBufferHeight");
return DrawingBufferSize().height;
} }
layers::LayersBackend GetCompositorBackendType() const; layers::LayersBackend GetCompositorBackendType() const;
@ -518,7 +548,9 @@ public:
void void
GetContextAttributes(dom::Nullable<dom::WebGLContextAttributes>& retval); GetContextAttributes(dom::Nullable<dom::WebGLContextAttributes>& retval);
bool IsContextLost() const { return mContextStatus != ContextNotLost; } // This is the entrypoint. Don't test against it directly.
bool IsContextLost() const;
void GetSupportedExtensions(dom::Nullable< nsTArray<nsString> >& retval, void GetSupportedExtensions(dom::Nullable< nsTArray<nsString> >& retval,
dom::CallerType callerType); dom::CallerType callerType);
void GetExtension(JSContext* cx, const nsAString& name, void GetExtension(JSContext* cx, const nsAString& name,
@ -649,11 +681,15 @@ public:
GetUniformLocation(const WebGLProgram& prog, const nsAString& name); GetUniformLocation(const WebGLProgram& prog, const nsAString& name);
void Hint(GLenum target, GLenum mode); void Hint(GLenum target, GLenum mode);
bool IsFramebuffer(const WebGLFramebuffer* fb);
bool IsProgram(const WebGLProgram* prog); bool IsBuffer(const WebGLBuffer* obj);
bool IsRenderbuffer(const WebGLRenderbuffer* rb); bool IsFramebuffer(const WebGLFramebuffer* obj);
bool IsShader(const WebGLShader* shader); bool IsProgram(const WebGLProgram* obj);
bool IsVertexArray(const WebGLVertexArray* vao); bool IsRenderbuffer(const WebGLRenderbuffer* obj);
bool IsShader(const WebGLShader* obj);
bool IsTexture(const WebGLTexture* obj);
bool IsVertexArray(const WebGLVertexArray* obj);
void LineWidth(GLfloat width); void LineWidth(GLfloat width);
void LinkProgram(WebGLProgram& prog); void LinkProgram(WebGLProgram& prog);
void PixelStorei(GLenum pname, GLint param); void PixelStorei(GLenum pname, GLint param);
@ -680,11 +716,9 @@ public:
GLenum type, const dom::Nullable<dom::ArrayBufferView>& maybeView, GLenum type, const dom::Nullable<dom::ArrayBufferView>& maybeView,
dom::CallerType aCallerType, ErrorResult& rv) dom::CallerType aCallerType, ErrorResult& rv)
{ {
const char funcName[] = "readPixels"; const FuncScope funcScope(*this, "readPixels");
if (maybeView.IsNull()) { if (!ValidateNonNull("pixels", maybeView))
ErrorInvalidValue("%s: `pixels` must not be null.", funcName);
return; return;
}
ReadPixels(x, y, width, height, format, type, maybeView.Value(), 0, ReadPixels(x, y, width, height, format, type, maybeView.Value(), 0,
aCallerType, rv); aCallerType, rv);
} }
@ -700,10 +734,13 @@ public:
//// ////
void RenderbufferStorage(GLenum target, GLenum internalFormat, void RenderbufferStorage(GLenum target, GLenum internalFormat,
GLsizei width, GLsizei height); GLsizei width, GLsizei height)
{
const FuncScope funcScope(*this, "renderbufferStorage");
RenderbufferStorage_base(target, 0, internalFormat, width, height);
}
protected: protected:
void RenderbufferStorage_base(const char* funcName, GLenum target, void RenderbufferStorage_base(GLenum target, GLsizei samples, GLenum internalformat,
GLsizei samples, GLenum internalformat,
GLsizei width, GLsizei height); GLsizei width, GLsizei height);
public: public:
void SampleCoverage(GLclampf value, WebGLboolean invert); void SampleCoverage(GLclampf value, WebGLboolean invert);
@ -892,14 +929,13 @@ public:
void UseProgram(WebGLProgram* prog); void UseProgram(WebGLProgram* prog);
bool ValidateAttribArraySetter(const char* name, uint32_t count, bool ValidateAttribArraySetter(uint32_t count, uint32_t arrayLength);
uint32_t arrayLength); bool ValidateUniformLocation(WebGLUniformLocation* loc);
bool ValidateUniformLocation(WebGLUniformLocation* loc, const char* funcName);
bool ValidateUniformSetter(WebGLUniformLocation* loc, uint8_t setterSize, bool ValidateUniformSetter(WebGLUniformLocation* loc, uint8_t setterSize,
GLenum setterType, const char* funcName); GLenum setterType);
bool ValidateUniformArraySetter(WebGLUniformLocation* loc, bool ValidateUniformArraySetter(WebGLUniformLocation* loc,
uint8_t setterElemSize, GLenum setterType, uint8_t setterElemSize, GLenum setterType,
uint32_t setterArraySize, const char* funcName, uint32_t setterArraySize,
uint32_t* out_numElementsToUpload); uint32_t* out_numElementsToUpload);
bool ValidateUniformMatrixArraySetter(WebGLUniformLocation* loc, bool ValidateUniformMatrixArraySetter(WebGLUniformLocation* loc,
uint8_t setterCols, uint8_t setterCols,
@ -907,7 +943,6 @@ public:
GLenum setterType, GLenum setterType,
uint32_t setterArraySize, uint32_t setterArraySize,
bool setterTranspose, bool setterTranspose,
const char* funcName,
uint32_t* out_numElementsToUpload); uint32_t* out_numElementsToUpload);
void ValidateProgram(const WebGLProgram& prog); void ValidateProgram(const WebGLProgram& prog);
bool ValidateUniformLocation(const char* info, WebGLUniformLocation* loc); bool ValidateUniformLocation(const char* info, WebGLUniformLocation* loc);
@ -952,7 +987,6 @@ public:
already_AddRefed<WebGLBuffer> CreateBuffer(); already_AddRefed<WebGLBuffer> CreateBuffer();
void DeleteBuffer(WebGLBuffer* buf); void DeleteBuffer(WebGLBuffer* buf);
bool IsBuffer(WebGLBuffer* buf);
protected: protected:
// bound buffer state // bound buffer state
@ -978,18 +1012,18 @@ protected:
WebGLRefPtr<WebGLQuery> mQuerySlot_TimeElapsed; WebGLRefPtr<WebGLQuery> mQuerySlot_TimeElapsed;
WebGLRefPtr<WebGLQuery>* WebGLRefPtr<WebGLQuery>*
ValidateQuerySlotByTarget(const char* funcName, GLenum target); ValidateQuerySlotByTarget(GLenum target);
public: public:
already_AddRefed<WebGLQuery> CreateQuery(const char* funcName = nullptr); already_AddRefed<WebGLQuery> CreateQuery();
void DeleteQuery(WebGLQuery* query, const char* funcName = nullptr); void DeleteQuery(WebGLQuery* query);
bool IsQuery(const WebGLQuery* query, const char* funcName = nullptr); bool IsQuery(const WebGLQuery* query);
void BeginQuery(GLenum target, WebGLQuery& query, const char* funcName = nullptr); void BeginQuery(GLenum target, WebGLQuery& query);
void EndQuery(GLenum target, const char* funcName = nullptr); void EndQuery(GLenum target);
void GetQuery(JSContext* cx, GLenum target, GLenum pname, void GetQuery(JSContext* cx, GLenum target, GLenum pname,
JS::MutableHandleValue retval, const char* funcName = nullptr); JS::MutableHandleValue retval);
void GetQueryParameter(JSContext* cx, const WebGLQuery& query, GLenum pname, void GetQueryParameter(JSContext* cx, const WebGLQuery& query, GLenum pname,
JS::MutableHandleValue retval, const char* funcName = nullptr); JS::MutableHandleValue retval);
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
@ -1021,7 +1055,7 @@ private:
realGLboolean mStencilTestEnabled; realGLboolean mStencilTestEnabled;
GLenum mGenerateMipmapHint = 0; GLenum mGenerateMipmapHint = 0;
bool ValidateCapabilityEnum(GLenum cap, const char* info); bool ValidateCapabilityEnum(GLenum cap);
realGLboolean* GetStateTrackingSlot(GLenum cap); realGLboolean* GetStateTrackingSlot(GLenum cap);
// Allocation debugging variables // Allocation debugging variables
@ -1052,8 +1086,6 @@ public:
retval.set(GetTexParameter(texTarget, pname)); retval.set(GetTexParameter(texTarget, pname));
} }
bool IsTexture(WebGLTexture* tex);
void TexParameterf(GLenum texTarget, GLenum pname, GLfloat param) { void TexParameterf(GLenum texTarget, GLenum pname, GLfloat param) {
TexParameter_base(texTarget, pname, FloatOrInt(param)); TexParameter_base(texTarget, pname, FloatOrInt(param));
} }
@ -1075,11 +1107,11 @@ public:
GLsizei width, GLsizei height, GLint border, GLsizei width, GLsizei height, GLint border,
GLsizei imageSize, WebGLsizeiptr offset) GLsizei imageSize, WebGLsizeiptr offset)
{ {
const char funcName[] = "compressedTexImage2D"; const FuncScope funcScope(*this, "compressedTexImage2D");
const uint8_t funcDims = 2; const uint8_t funcDims = 2;
const GLsizei depth = 1; const GLsizei depth = 1;
const TexImageSourceAdapter src(&offset, 0, 0); const TexImageSourceAdapter src(&offset, 0, 0);
CompressedTexImage(funcName, funcDims, target, level, internalFormat, width, CompressedTexImage(funcDims, target, level, internalFormat, width,
height, depth, border, src, Some(imageSize)); height, depth, border, src, Some(imageSize));
} }
@ -1089,11 +1121,11 @@ public:
const T& anySrc, GLuint viewElemOffset = 0, const T& anySrc, GLuint viewElemOffset = 0,
GLuint viewElemLengthOverride = 0) GLuint viewElemLengthOverride = 0)
{ {
const char funcName[] = "compressedTexImage2D"; const FuncScope funcScope(*this, "compressedTexImage2D");
const uint8_t funcDims = 2; const uint8_t funcDims = 2;
const GLsizei depth = 1; const GLsizei depth = 1;
const TexImageSourceAdapter src(&anySrc, viewElemOffset, viewElemLengthOverride); const TexImageSourceAdapter src(&anySrc, viewElemOffset, viewElemLengthOverride);
CompressedTexImage(funcName, funcDims, target, level, internalFormat, width, CompressedTexImage(funcDims, target, level, internalFormat, width,
height, depth, border, src, Nothing()); height, depth, border, src, Nothing());
} }
@ -1101,12 +1133,12 @@ public:
GLsizei width, GLsizei height, GLenum unpackFormat, GLsizei width, GLsizei height, GLenum unpackFormat,
GLsizei imageSize, WebGLsizeiptr offset) GLsizei imageSize, WebGLsizeiptr offset)
{ {
const char funcName[] = "compressedTexSubImage2D"; const FuncScope funcScope(*this, "compressedTexSubImage2D");
const uint8_t funcDims = 2; const uint8_t funcDims = 2;
const GLint zOffset = 0; const GLint zOffset = 0;
const GLsizei depth = 1; const GLsizei depth = 1;
const TexImageSourceAdapter src(&offset, 0, 0); const TexImageSourceAdapter src(&offset, 0, 0);
CompressedTexSubImage(funcName, funcDims, target, level, xOffset, yOffset, CompressedTexSubImage(funcDims, target, level, xOffset, yOffset,
zOffset, width, height, depth, unpackFormat, src, Some(imageSize)); zOffset, width, height, depth, unpackFormat, src, Some(imageSize));
} }
@ -1116,25 +1148,26 @@ public:
const T& anySrc, GLuint viewElemOffset = 0, const T& anySrc, GLuint viewElemOffset = 0,
GLuint viewElemLengthOverride = 0) GLuint viewElemLengthOverride = 0)
{ {
const char funcName[] = "compressedTexSubImage2D"; const FuncScope funcScope(*this, "compressedTexSubImage2D");
const uint8_t funcDims = 2; const uint8_t funcDims = 2;
const GLint zOffset = 0; const GLint zOffset = 0;
const GLsizei depth = 1; const GLsizei depth = 1;
const TexImageSourceAdapter src(&anySrc, viewElemOffset, viewElemLengthOverride); const TexImageSourceAdapter src(&anySrc, viewElemOffset, viewElemLengthOverride);
CompressedTexSubImage(funcName, funcDims, target, level, xOffset, yOffset, CompressedTexSubImage(funcDims, target, level, xOffset, yOffset,
zOffset, width, height, depth, unpackFormat, src, Nothing()); zOffset, width, height, depth, unpackFormat, src, Nothing());
} }
protected: protected:
void CompressedTexImage(const char* funcName, uint8_t funcDims, GLenum target, void CompressedTexImage(uint8_t funcDims, GLenum target,
GLint level, GLenum internalFormat, GLsizei width, GLint level, GLenum internalFormat, GLsizei width,
GLsizei height, GLsizei depth, GLint border, GLsizei height, GLsizei depth, GLint border,
const TexImageSource& src, const Maybe<GLsizei>& expectedImageSize); const TexImageSource& src, const Maybe<GLsizei>& expectedImageSize);
void CompressedTexSubImage(const char* funcName, uint8_t funcDims, GLenum target, void CompressedTexSubImage(uint8_t funcDims, GLenum target,
GLint level, GLint xOffset, GLint yOffset, GLint zOffset, GLint level, GLint xOffset, GLint yOffset, GLint zOffset,
GLsizei width, GLsizei height, GLsizei depth, GLsizei width, GLsizei height, GLsizei depth,
GLenum unpackFormat, const TexImageSource& src, GLenum unpackFormat, const TexImageSource& src,
const Maybe<GLsizei>& expectedImageSize); const Maybe<GLsizei>& expectedImageSize);
//////////////////////////////////// ////////////////////////////////////
public: public:
@ -1145,15 +1178,15 @@ public:
GLint yOffset, GLint x, GLint y, GLsizei width, GLint yOffset, GLint x, GLint y, GLsizei width,
GLsizei height) GLsizei height)
{ {
const char funcName[] = "copyTexSubImage2D"; const FuncScope funcScope(*this, "copyTexSubImage2D");
const uint8_t funcDims = 2; const uint8_t funcDims = 2;
const GLint zOffset = 0; const GLint zOffset = 0;
CopyTexSubImage(funcName, funcDims, target, level, xOffset, yOffset, zOffset, CopyTexSubImage(funcDims, target, level, xOffset, yOffset, zOffset,
x, y, width, height); x, y, width, height);
} }
protected: protected:
void CopyTexSubImage(const char* funcName, uint8_t funcDims, GLenum target, void CopyTexSubImage(uint8_t funcDims, GLenum target,
GLint level, GLint xOffset, GLint yOffset, GLint zOffset, GLint level, GLint xOffset, GLint yOffset, GLint zOffset,
GLint x, GLint y, GLsizei width, GLsizei height); GLint x, GLint y, GLsizei width, GLsizei height);
@ -1213,14 +1246,14 @@ protected:
GLsizei height, GLint border, GLenum unpackFormat, GLsizei height, GLint border, GLenum unpackFormat,
GLenum unpackType, const TexImageSource& src) GLenum unpackType, const TexImageSource& src)
{ {
const char funcName[] = "texImage2D"; const FuncScope funcScope(*this, "texImage2D");
const uint8_t funcDims = 2; const uint8_t funcDims = 2;
const GLsizei depth = 1; const GLsizei depth = 1;
TexImage(funcName, funcDims, target, level, internalFormat, width, height, depth, TexImage(funcDims, target, level, internalFormat, width, height, depth,
border, unpackFormat, unpackType, src); border, unpackFormat, unpackType, src);
} }
void TexImage(const char* funcName, uint8_t funcDims, GLenum target, GLint level, void TexImage(uint8_t funcDims, GLenum target, GLint level,
GLenum internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLenum internalFormat, GLsizei width, GLsizei height, GLsizei depth,
GLint border, GLenum unpackFormat, GLenum unpackType, GLint border, GLenum unpackFormat, GLenum unpackType,
const TexImageSource& src); const TexImageSource& src);
@ -1253,15 +1286,15 @@ protected:
GLsizei width, GLsizei height, GLenum unpackFormat, GLsizei width, GLsizei height, GLenum unpackFormat,
GLenum unpackType, const TexImageSource& src) GLenum unpackType, const TexImageSource& src)
{ {
const char funcName[] = "texSubImage2D"; const FuncScope funcScope(*this, "texSubImage2D");
const uint8_t funcDims = 2; const uint8_t funcDims = 2;
const GLint zOffset = 0; const GLint zOffset = 0;
const GLsizei depth = 1; const GLsizei depth = 1;
TexSubImage(funcName, funcDims, target, level, xOffset, yOffset, zOffset, width, TexSubImage(funcDims, target, level, xOffset, yOffset, zOffset, width,
height, depth, unpackFormat, unpackType, src); height, depth, unpackFormat, unpackType, src);
} }
void TexSubImage(const char* funcName, uint8_t funcDims, GLenum target, GLint level, void TexSubImage(uint8_t funcDims, GLenum target, GLint level,
GLint xOffset, GLint yOffset, GLint zOffset, GLsizei width, GLint xOffset, GLint yOffset, GLint zOffset, GLsizei width,
GLsizei height, GLsizei depth, GLenum unpackFormat, GLsizei height, GLsizei depth, GLenum unpackFormat,
GLenum unpackType, const TexImageSource& src); GLenum unpackType, const TexImageSource& src);
@ -1270,35 +1303,35 @@ protected:
// WebGLTextureUpload.cpp // WebGLTextureUpload.cpp
public: public:
UniquePtr<webgl::TexUnpackBlob> UniquePtr<webgl::TexUnpackBlob>
From(const char* funcName, TexImageTarget target, GLsizei rawWidth, GLsizei rawHeight, From(TexImageTarget target, GLsizei rawWidth, GLsizei rawHeight,
GLsizei rawDepth, GLint border, const TexImageSource& src, GLsizei rawDepth, GLint border, const TexImageSource& src,
dom::Uint8ClampedArray* const scopedArr); dom::Uint8ClampedArray* const scopedArr);
protected: protected:
bool ValidateTexImageSpecification(const char* funcName, uint8_t funcDims, bool ValidateTexImageSpecification(uint8_t funcDims,
GLenum texImageTarget, GLint level, GLenum texImageTarget, GLint level,
GLsizei width, GLsizei height, GLsizei depth, GLsizei width, GLsizei height, GLsizei depth,
GLint border, GLint border,
TexImageTarget* const out_target, TexImageTarget* const out_target,
WebGLTexture** const out_texture, WebGLTexture** const out_texture,
WebGLTexture::ImageInfo** const out_imageInfo); WebGLTexture::ImageInfo** const out_imageInfo);
bool ValidateTexImageSelection(const char* funcName, uint8_t funcDims, bool ValidateTexImageSelection(uint8_t funcDims,
GLenum texImageTarget, GLint level, GLint xOffset, GLenum texImageTarget, GLint level, GLint xOffset,
GLint yOffset, GLint zOffset, GLsizei width, GLint yOffset, GLint zOffset, GLsizei width,
GLsizei height, GLsizei depth, GLsizei height, GLsizei depth,
TexImageTarget* const out_target, TexImageTarget* const out_target,
WebGLTexture** const out_texture, WebGLTexture** const out_texture,
WebGLTexture::ImageInfo** const out_imageInfo); WebGLTexture::ImageInfo** const out_imageInfo);
bool ValidateUnpackInfo(const char* funcName, bool usePBOs, GLenum format, bool ValidateUnpackInfo(bool usePBOs, GLenum format,
GLenum type, webgl::PackingInfo* const out); GLenum type, webgl::PackingInfo* const out);
UniquePtr<webgl::TexUnpackBlob> UniquePtr<webgl::TexUnpackBlob>
FromDomElem(const char* funcName, TexImageTarget target, uint32_t width, FromDomElem(TexImageTarget target, uint32_t width,
uint32_t height, uint32_t depth, const dom::Element& elem, uint32_t height, uint32_t depth, const dom::Element& elem,
ErrorResult* const out_error); ErrorResult* const out_error);
UniquePtr<webgl::TexUnpackBytes> UniquePtr<webgl::TexUnpackBytes>
FromCompressed(const char* funcName, TexImageTarget target, GLsizei rawWidth, FromCompressed(TexImageTarget target, GLsizei rawWidth,
GLsizei rawHeight, GLsizei rawDepth, GLint border, GLsizei rawHeight, GLsizei rawDepth, GLint border,
const TexImageSource& src, const Maybe<GLsizei>& expectedImageSize); const TexImageSource& src, const Maybe<GLsizei>& expectedImageSize);
@ -1308,21 +1341,21 @@ protected:
public: public:
void DrawArrays(GLenum mode, GLint first, GLsizei count) { void DrawArrays(GLenum mode, GLint first, GLsizei count) {
DrawArraysInstanced(mode, first, count, 1, "drawArrays"); const FuncScope funcScope(*this, "drawArrays");
DrawArraysInstanced(mode, first, count, 1);
} }
void DrawElements(GLenum mode, GLsizei count, GLenum type, void DrawElements(GLenum mode, GLsizei count, GLenum type,
WebGLintptr byteOffset, const char* funcName = "drawElements") WebGLintptr byteOffset)
{ {
DrawElementsInstanced(mode, count, type, byteOffset, 1, funcName); const FuncScope funcScope(*this, "drawElements");
DrawElementsInstanced(mode, count, type, byteOffset, 1);
} }
void DrawArraysInstanced(GLenum mode, GLint first, GLsizei vertexCount, void DrawArraysInstanced(GLenum mode, GLint first, GLsizei vertexCount,
GLsizei instanceCount, GLsizei instanceCount);
const char* funcName = "drawArraysInstanced");
void DrawElementsInstanced(GLenum mode, GLsizei vertexCount, GLenum type, void DrawElementsInstanced(GLenum mode, GLsizei vertexCount, GLenum type,
WebGLintptr byteOffset, GLsizei instanceCount, WebGLintptr byteOffset, GLsizei instanceCount);
const char* funcName = "drawElementsInstanced");
void EnableVertexAttribArray(GLuint index); void EnableVertexAttribArray(GLuint index);
void DisableVertexAttribArray(GLuint index); void DisableVertexAttribArray(GLuint index);
@ -1340,65 +1373,66 @@ public:
//// ////
void VertexAttrib4f(GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w, void VertexAttrib4f(GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w);
const char* funcName = nullptr);
//// ////
void VertexAttrib1f(GLuint index, GLfloat x) { void VertexAttrib1f(GLuint index, GLfloat x) {
VertexAttrib4f(index, x, 0, 0, 1, "vertexAttrib1f"); const FuncScope funcScope(*this, "vertexAttrib1f");
VertexAttrib4f(index, x, 0, 0, 1);
} }
void VertexAttrib2f(GLuint index, GLfloat x, GLfloat y) { void VertexAttrib2f(GLuint index, GLfloat x, GLfloat y) {
VertexAttrib4f(index, x, y, 0, 1, "vertexAttrib2f"); const FuncScope funcScope(*this, "vertexAttrib2f");
VertexAttrib4f(index, x, y, 0, 1);
} }
void VertexAttrib3f(GLuint index, GLfloat x, GLfloat y, GLfloat z) { void VertexAttrib3f(GLuint index, GLfloat x, GLfloat y, GLfloat z) {
VertexAttrib4f(index, x, y, z, 1, "vertexAttrib3f"); const FuncScope funcScope(*this, "vertexAttrib3f");
VertexAttrib4f(index, x, y, z, 1);
} }
//// ////
void VertexAttrib1fv(GLuint index, const Float32ListU& list) { void VertexAttrib1fv(GLuint index, const Float32ListU& list) {
const char funcName[] = "vertexAttrib1fv"; const FuncScope funcScope(*this, "vertexAttrib1fv");
const auto& arr = Float32Arr::From(list); const auto& arr = Float32Arr::From(list);
if (!ValidateAttribArraySetter(funcName, 1, arr.elemCount)) if (!ValidateAttribArraySetter(1, arr.elemCount))
return; return;
VertexAttrib4f(index, arr.elemBytes[0], 0, 0, 1, funcName); VertexAttrib4f(index, arr.elemBytes[0], 0, 0, 1);
} }
void VertexAttrib2fv(GLuint index, const Float32ListU& list) { void VertexAttrib2fv(GLuint index, const Float32ListU& list) {
const char funcName[] = "vertexAttrib2fv"; const FuncScope funcScope(*this, "vertexAttrib2fv");
const auto& arr = Float32Arr::From(list); const auto& arr = Float32Arr::From(list);
if (!ValidateAttribArraySetter(funcName, 2, arr.elemCount)) if (!ValidateAttribArraySetter(2, arr.elemCount))
return; return;
VertexAttrib4f(index, arr.elemBytes[0], arr.elemBytes[1], 0, 1, funcName); VertexAttrib4f(index, arr.elemBytes[0], arr.elemBytes[1], 0, 1);
} }
void VertexAttrib3fv(GLuint index, const Float32ListU& list) { void VertexAttrib3fv(GLuint index, const Float32ListU& list) {
const char funcName[] = "vertexAttrib3fv"; const FuncScope funcScope(*this, "vertexAttrib3fv");
const auto& arr = Float32Arr::From(list); const auto& arr = Float32Arr::From(list);
if (!ValidateAttribArraySetter(funcName, 3, arr.elemCount)) if (!ValidateAttribArraySetter(3, arr.elemCount))
return; return;
VertexAttrib4f(index, arr.elemBytes[0], arr.elemBytes[1], arr.elemBytes[2], 1, VertexAttrib4f(index, arr.elemBytes[0], arr.elemBytes[1], arr.elemBytes[2], 1);
funcName);
} }
void VertexAttrib4fv(GLuint index, const Float32ListU& list) { void VertexAttrib4fv(GLuint index, const Float32ListU& list) {
const char funcName[] = "vertexAttrib4fv"; const FuncScope funcScope(*this, "vertexAttrib4fv");
const auto& arr = Float32Arr::From(list); const auto& arr = Float32Arr::From(list);
if (!ValidateAttribArraySetter(funcName, 4, arr.elemCount)) if (!ValidateAttribArraySetter(4, arr.elemCount))
return; return;
VertexAttrib4f(index, arr.elemBytes[0], arr.elemBytes[1], arr.elemBytes[2], VertexAttrib4f(index, arr.elemBytes[0], arr.elemBytes[1], arr.elemBytes[2],
arr.elemBytes[3], funcName); arr.elemBytes[3]);
} }
//// ////
protected: protected:
void VertexAttribAnyPointer(const char* funcName, bool isFuncInt, GLuint index, void VertexAttribAnyPointer(bool isFuncInt, GLuint index,
GLint size, GLenum type, bool normalized, GLsizei stride, GLint size, GLenum type, bool normalized, GLsizei stride,
WebGLintptr byteOffset); WebGLintptr byteOffset);
@ -1407,18 +1441,18 @@ public:
WebGLboolean normalized, GLsizei stride, WebGLboolean normalized, GLsizei stride,
WebGLintptr byteOffset) WebGLintptr byteOffset)
{ {
const char funcName[] = "vertexAttribPointer"; const FuncScope funcScope(*this, "vertexAttribPointer");
const bool isFuncInt = false; const bool isFuncInt = false;
VertexAttribAnyPointer(funcName, isFuncInt, index, size, type, normalized, stride, VertexAttribAnyPointer(isFuncInt, index, size, type, normalized, stride,
byteOffset); byteOffset);
} }
void VertexAttribDivisor(GLuint index, GLuint divisor); void VertexAttribDivisor(GLuint index, GLuint divisor);
private: private:
WebGLBuffer* DrawElements_check(const char* funcName, GLsizei indexCount, GLenum type, WebGLBuffer* DrawElements_check(GLsizei indexCount, GLenum type,
WebGLintptr byteOffset, GLsizei instanceCount); WebGLintptr byteOffset, GLsizei instanceCount);
void Draw_cleanup(const char* funcName); void Draw_cleanup();
void VertexAttrib1fv_base(GLuint index, uint32_t arrayLength, void VertexAttrib1fv_base(GLuint index, uint32_t arrayLength,
const GLfloat* ptr); const GLfloat* ptr);
@ -1435,7 +1469,7 @@ private:
// PROTECTED // PROTECTED
protected: protected:
WebGLVertexAttrib0Status WhatDoesVertexAttrib0Need() const; WebGLVertexAttrib0Status WhatDoesVertexAttrib0Need() const;
bool DoFakeVertexAttrib0(const char* funcName, uint64_t vertexCount); bool DoFakeVertexAttrib0(uint64_t vertexCount);
void UndoFakeVertexAttrib0(); void UndoFakeVertexAttrib0();
CheckedUint32 mGeneration; CheckedUint32 mGeneration;
@ -1528,19 +1562,19 @@ protected:
// process we currently are at. // process we currently are at.
// This is used to support the WebGL spec's asyncronous nature in handling // This is used to support the WebGL spec's asyncronous nature in handling
// context loss. // context loss.
enum ContextStatus { enum class ContextStatus {
// The context is stable; there either are none or we don't know of any. // The context is stable; there either are none or we don't know of any.
ContextNotLost, NotLost,
// The context has been lost, but we have not yet sent an event to the // The context has been lost, but we have not yet sent an event to the
// script informing it of this. // script informing it of this.
ContextLostAwaitingEvent, LostAwaitingEvent,
// The context has been lost, and we have sent the script an event // The context has been lost, and we have sent the script an event
// informing it of this. // informing it of this.
ContextLost, Lost,
// The context is lost, an event has been sent to the script, and the // The context is lost, an event has been sent to the script, and the
// script correctly handled the event. We are waiting for the context to // script correctly handled the event. We are waiting for the context to
// be restored. // be restored.
ContextLostAwaitingRestore LostAwaitingRestore
}; };
// ------------------------------------------------------------------------- // -------------------------------------------------------------------------
@ -1603,17 +1637,14 @@ protected:
bool ValidateBlendEquationEnum(GLenum cap, const char* info); bool ValidateBlendEquationEnum(GLenum cap, const char* info);
bool ValidateBlendFuncEnumsCompatibility(GLenum sfactor, GLenum dfactor, bool ValidateBlendFuncEnumsCompatibility(GLenum sfactor, GLenum dfactor,
const char* info); const char* info);
bool ValidateComparisonEnum(GLenum target, const char* info);
bool ValidateStencilOpEnum(GLenum action, const char* info); bool ValidateStencilOpEnum(GLenum action, const char* info);
bool ValidateFaceEnum(GLenum face, const char* info); bool ValidateFaceEnum(GLenum face);
bool ValidateTexInputData(GLenum type, js::Scalar::Type jsArrayType, bool ValidateTexInputData(GLenum type, js::Scalar::Type jsArrayType,
WebGLTexImageFunc func, WebGLTexDimensions dims); WebGLTexImageFunc func, WebGLTexDimensions dims);
bool ValidateDrawModeEnum(GLenum mode, const char* info);
bool ValidateAttribIndex(GLuint index, const char* info);
bool ValidateAttribPointer(bool integerMode, GLuint index, GLint size, GLenum type, bool ValidateAttribPointer(bool integerMode, GLuint index, GLint size, GLenum type,
WebGLboolean normalized, GLsizei stride, WebGLboolean normalized, GLsizei stride,
WebGLintptr byteOffset, const char* info); WebGLintptr byteOffset, const char* info);
bool ValidateStencilParamsForDrawCall(const char* funcName) const; bool ValidateStencilParamsForDrawCall() const;
bool ValidateCopyTexImage(TexInternalFormat srcFormat, TexInternalFormat dstformat, bool ValidateCopyTexImage(TexInternalFormat srcFormat, TexInternalFormat dstformat,
WebGLTexImageFunc func, WebGLTexDimensions dims); WebGLTexImageFunc func, WebGLTexDimensions dims);
@ -1657,28 +1688,26 @@ protected:
WebGLTexDimensions dims); WebGLTexDimensions dims);
bool ValidateUniformLocationForProgram(WebGLUniformLocation* location, bool ValidateUniformLocationForProgram(WebGLUniformLocation* location,
WebGLProgram* program, WebGLProgram* program);
const char* funcName);
bool HasDrawBuffers() const { bool HasDrawBuffers() const {
return IsWebGL2() || return IsWebGL2() ||
IsExtensionEnabled(WebGLExtensionID::WEBGL_draw_buffers); IsExtensionEnabled(WebGLExtensionID::WEBGL_draw_buffers);
} }
WebGLRefPtr<WebGLBuffer>* ValidateBufferSlot(const char* funcName, GLenum target); WebGLRefPtr<WebGLBuffer>* ValidateBufferSlot(GLenum target);
public: public:
WebGLBuffer* ValidateBufferSelection(const char* funcName, GLenum target); WebGLBuffer* ValidateBufferSelection(GLenum target);
protected: protected:
IndexedBufferBinding* ValidateIndexedBufferSlot(const char* funcName, GLenum target, IndexedBufferBinding* ValidateIndexedBufferSlot(GLenum target, GLuint index);
GLuint index);
bool ValidateIndexedBufferBinding(const char* funcName, GLenum target, GLuint index, bool ValidateIndexedBufferBinding(GLenum target, GLuint index,
WebGLRefPtr<WebGLBuffer>** const out_genericBinding, WebGLRefPtr<WebGLBuffer>** const out_genericBinding,
IndexedBufferBinding** const out_indexedBinding); IndexedBufferBinding** const out_indexedBinding);
bool ValidateNonNegative(const char* funcName, const char* argName, int64_t val) { bool ValidateNonNegative(const char* argName, int64_t val) {
if (MOZ_UNLIKELY(val < 0)) { if (MOZ_UNLIKELY(val < 0)) {
ErrorInvalidValue("%s: `%s` must be non-negative.", funcName, argName); ErrorInvalidValue("`%s` must be non-negative.", argName);
return false; return false;
} }
return true; return true;
@ -1686,15 +1715,15 @@ protected:
public: public:
template<typename T> template<typename T>
bool ValidateNonNull(const char* funcName, const dom::Nullable<T>& maybe) { bool ValidateNonNull(const char* const argName, const dom::Nullable<T>& maybe) {
if (maybe.IsNull()) { if (maybe.IsNull()) {
ErrorInvalidValue("%s: `null` is invalid.", funcName); ErrorInvalidValue("%s: Cannot be null.", argName);
return false; return false;
} }
return true; return true;
} }
bool ValidateArrayBufferView(const char* funcName, const dom::ArrayBufferView& view, bool ValidateArrayBufferView(const dom::ArrayBufferView& view,
GLuint elemOffset, GLuint elemCountOverride, GLuint elemOffset, GLuint elemCountOverride,
uint8_t** const out_bytes, size_t* const out_byteLen); uint8_t** const out_bytes, size_t* const out_byteLen);
@ -1714,23 +1743,23 @@ protected:
////// //////
public: public:
bool ValidateObjectAllowDeleted(const char* funcName, bool ValidateObjectAllowDeleted(const char* const argName,
const WebGLContextBoundObject& object) const WebGLContextBoundObject& object)
{ {
if (!object.IsCompatibleWithContext(this)) { if (!object.IsCompatibleWithContext(this)) {
ErrorInvalidOperation("%s: Object from different WebGL context (or older" ErrorInvalidOperation("%s: Object from different WebGL context (or older"
" generation of this one) passed as argument.", " generation of this one) passed as argument.",
funcName); argName);
return false; return false;
} }
return true; return true;
} }
bool ValidateObject(const char* funcName, const WebGLDeletableObject& object, bool ValidateObject(const char* const argName, const WebGLDeletableObject& object,
bool isShaderOrProgram = false) const bool isShaderOrProgram = false)
{ {
if (!ValidateObjectAllowDeleted(funcName, object)) if (!ValidateObjectAllowDeleted(argName, object))
return false; return false;
if (isShaderOrProgram) { if (isShaderOrProgram) {
@ -1746,14 +1775,14 @@ public:
if (object.IsDeleted()) { if (object.IsDeleted()) {
ErrorInvalidValue("%s: Shader or program object argument cannot have been" ErrorInvalidValue("%s: Shader or program object argument cannot have been"
" deleted.", " deleted.",
funcName); argName);
return false; return false;
} }
} else { } else {
if (object.IsDeleteRequested()) { if (object.IsDeleteRequested()) {
ErrorInvalidOperation("%s: Object argument cannot have been marked for" ErrorInvalidOperation("%s: Object argument cannot have been marked for"
" deletion.", " deletion.",
funcName); argName);
return false; return false;
} }
} }
@ -1763,44 +1792,15 @@ public:
//// ////
bool ValidateObject(const char* funcName, const WebGLProgram& object); // Program and Shader are incomplete, so we can't inline the conversion to
bool ValidateObject(const char* funcName, const WebGLShader& object); // WebGLDeletableObject here.
bool ValidateObject(const char* const argName, const WebGLProgram& object);
bool ValidateObject(const char* const argName, const WebGLShader& object);
//// ////
bool ValidateIsObject(const char* funcName, bool ValidateIsObject(const WebGLDeletableObject* object) const;
const WebGLDeletableObject* object) const bool ValidateDeleteObject(const WebGLDeletableObject* object);
{
if (IsContextLost())
return false;
if (!object)
return false;
if (!object->IsCompatibleWithContext(this))
return false;
if (object->IsDeleted())
return false;
return true;
}
bool ValidateDeleteObject(const char* funcName, const WebGLDeletableObject* object) {
if (IsContextLost())
return false;
if (!object)
return false;
if (!ValidateObjectAllowDeleted(funcName, *object))
return false;
if (object->IsDeleteRequested())
return false;
return true;
}
//// ////
@ -1826,8 +1826,8 @@ protected:
WebGLRefPtr<WebGLProgram> mCurrentProgram; WebGLRefPtr<WebGLProgram> mCurrentProgram;
RefPtr<const webgl::LinkedProgramInfo> mActiveProgramLinkInfo; RefPtr<const webgl::LinkedProgramInfo> mActiveProgramLinkInfo;
bool ValidateFramebufferTarget(GLenum target, const char* const info); bool ValidateFramebufferTarget(GLenum target);
bool ValidateInvalidateFramebuffer(const char* funcName, GLenum target, bool ValidateInvalidateFramebuffer(GLenum target,
const dom::Sequence<GLenum>& attachments, const dom::Sequence<GLenum>& attachments,
ErrorResult* const out_rv, ErrorResult* const out_rv,
std::vector<GLenum>* const scopedVector, std::vector<GLenum>* const scopedVector,
@ -1870,7 +1870,7 @@ protected:
CheckedUint32 GetUnpackSize(bool isFunc3D, uint32_t width, uint32_t height, CheckedUint32 GetUnpackSize(bool isFunc3D, uint32_t width, uint32_t height,
uint32_t depth, uint8_t bytesPerPixel); uint32_t depth, uint8_t bytesPerPixel);
bool ValidatePackSize(const char* funcName, uint32_t width, uint32_t height, bool ValidatePackSize(uint32_t width, uint32_t height,
uint8_t bytesPerPixel, uint32_t* const out_rowStride, uint8_t bytesPerPixel, uint32_t* const out_rowStride,
uint32_t* const out_endOffset); uint32_t* const out_endOffset);
@ -1949,7 +1949,7 @@ protected:
WebGLContextLossHandler mContextLossHandler; WebGLContextLossHandler mContextLossHandler;
bool mAllowContextRestore; bool mAllowContextRestore;
bool mLastLossWasSimulated; bool mLastLossWasSimulated;
ContextStatus mContextStatus; ContextStatus mContextStatus = ContextStatus::NotLost;
bool mContextLostErrorSet; bool mContextLostErrorSet;
// Used for some hardware (particularly Tegra 2 and 4) that likes to // Used for some hardware (particularly Tegra 2 and 4) that likes to
@ -1993,17 +1993,16 @@ protected:
// -- // --
bool EnsureDefaultFB(const char* funcName); bool EnsureDefaultFB();
bool ValidateAndInitFB(const char* funcName, const WebGLFramebuffer* fb); bool ValidateAndInitFB(const WebGLFramebuffer* fb);
void DoBindFB(const WebGLFramebuffer* fb, GLenum target = LOCAL_GL_FRAMEBUFFER) const; void DoBindFB(const WebGLFramebuffer* fb, GLenum target = LOCAL_GL_FRAMEBUFFER) const;
bool BindCurFBForDraw(const char* funcName); bool BindCurFBForDraw();
bool BindCurFBForColorRead(const char* funcName, bool BindCurFBForColorRead(const webgl::FormatUsageInfo** out_format,
const webgl::FormatUsageInfo** out_format,
uint32_t* out_width, uint32_t* out_height); uint32_t* out_width, uint32_t* out_height);
void DoColorMask(uint8_t bitmask) const; void DoColorMask(uint8_t bitmask) const;
void BlitBackbufferToCurDriverFB() const; void BlitBackbufferToCurDriverFB() const;
bool BindDefaultFBForRead(const char* funcName); bool BindDefaultFBForRead();
// -- // --
@ -2083,12 +2082,15 @@ RoundUpToMultipleOf(const V& value, const M& multiple)
return ((value + multiple - 1) / multiple) * multiple; return ((value + multiple - 1) / multiple) * multiple;
} }
const char* GetEnumName(GLenum val, const char* defaultRet = "<unknown>");
std::string EnumString(GLenum val);
bool bool
ValidateTexTarget(WebGLContext* webgl, const char* funcName, uint8_t funcDims, ValidateTexTarget(WebGLContext* webgl, uint8_t funcDims,
GLenum rawTexTarget, TexTarget* const out_texTarget, GLenum rawTexTarget, TexTarget* const out_texTarget,
WebGLTexture** const out_tex); WebGLTexture** const out_tex);
bool bool
ValidateTexImageTarget(WebGLContext* webgl, const char* funcName, uint8_t funcDims, ValidateTexImageTarget(WebGLContext* webgl, uint8_t funcDims,
GLenum rawTexImageTarget, TexImageTarget* const out_texImageTarget, GLenum rawTexImageTarget, TexImageTarget* const out_texImageTarget,
WebGLTexture** const out_tex); WebGLTexture** const out_tex);

Просмотреть файл

@ -13,7 +13,7 @@
namespace mozilla { namespace mozilla {
WebGLRefPtr<WebGLBuffer>* WebGLRefPtr<WebGLBuffer>*
WebGLContext::ValidateBufferSlot(const char* funcName, GLenum target) WebGLContext::ValidateBufferSlot(GLenum target)
{ {
WebGLRefPtr<WebGLBuffer>* slot = nullptr; WebGLRefPtr<WebGLBuffer>* slot = nullptr;
@ -56,7 +56,7 @@ WebGLContext::ValidateBufferSlot(const char* funcName, GLenum target)
} }
if (!slot) { if (!slot) {
ErrorInvalidEnum("%s: Bad `target`: 0x%04x", funcName, target); ErrorInvalidEnumInfo("target", target);
return nullptr; return nullptr;
} }
@ -64,36 +64,33 @@ WebGLContext::ValidateBufferSlot(const char* funcName, GLenum target)
} }
WebGLBuffer* WebGLBuffer*
WebGLContext::ValidateBufferSelection(const char* funcName, GLenum target) WebGLContext::ValidateBufferSelection(GLenum target)
{ {
const auto& slot = ValidateBufferSlot(funcName, target); const auto& slot = ValidateBufferSlot(target);
if (!slot) if (!slot)
return nullptr; return nullptr;
const auto& buffer = *slot; const auto& buffer = *slot;
if (!buffer) { if (!buffer) {
ErrorInvalidOperation("%s: Buffer for `target` is null.", funcName); ErrorInvalidOperation("Buffer for `target` is null.");
return nullptr; return nullptr;
} }
if (target == LOCAL_GL_TRANSFORM_FEEDBACK_BUFFER) { if (target == LOCAL_GL_TRANSFORM_FEEDBACK_BUFFER) {
if (mBoundTransformFeedback->IsActiveAndNotPaused()) { if (mBoundTransformFeedback->IsActiveAndNotPaused()) {
ErrorInvalidOperation("%s: Cannot select TRANSFORM_FEEDBACK_BUFFER when" ErrorInvalidOperation("Cannot select TRANSFORM_FEEDBACK_BUFFER when"
" transform feedback is active and unpaused.", " transform feedback is active and unpaused.");
funcName);
return nullptr; return nullptr;
} }
if (buffer->IsBoundForNonTF()) { if (buffer->IsBoundForNonTF()) {
ErrorInvalidOperation("%s: Specified WebGLBuffer is currently bound for" ErrorInvalidOperation("Specified WebGLBuffer is currently bound for"
" non-transform-feedback.", " non-transform-feedback.");
funcName);
return nullptr; return nullptr;
} }
} else { } else {
if (buffer->IsBoundForTF()) { if (buffer->IsBoundForTF()) {
ErrorInvalidOperation("%s: Specified WebGLBuffer is currently bound for" ErrorInvalidOperation("Specified WebGLBuffer is currently bound for"
" transform feedback.", " transform feedback.");
funcName);
return nullptr; return nullptr;
} }
} }
@ -102,7 +99,7 @@ WebGLContext::ValidateBufferSelection(const char* funcName, GLenum target)
} }
IndexedBufferBinding* IndexedBufferBinding*
WebGLContext::ValidateIndexedBufferSlot(const char* funcName, GLenum target, GLuint index) WebGLContext::ValidateIndexedBufferSlot(GLenum target, GLuint index)
{ {
decltype(mIndexedUniformBufferBindings)* bindings; decltype(mIndexedUniformBufferBindings)* bindings;
const char* maxIndexEnum; const char* maxIndexEnum;
@ -118,12 +115,12 @@ WebGLContext::ValidateIndexedBufferSlot(const char* funcName, GLenum target, GLu
break; break;
default: default:
ErrorInvalidEnum("%s: Bad `target`: 0x%04x", funcName, target); ErrorInvalidEnumInfo("target", target);
return nullptr; return nullptr;
} }
if (index >= bindings->size()) { if (index >= bindings->size()) {
ErrorInvalidValue("%s: `index` >= %s.", funcName, maxIndexEnum); ErrorInvalidValue("`index` >= %s.", maxIndexEnum);
return nullptr; return nullptr;
} }
@ -135,18 +132,18 @@ WebGLContext::ValidateIndexedBufferSlot(const char* funcName, GLenum target, GLu
void void
WebGLContext::BindBuffer(GLenum target, WebGLBuffer* buffer) WebGLContext::BindBuffer(GLenum target, WebGLBuffer* buffer)
{ {
const char funcName[] = "bindBuffer"; const FuncScope funcScope(*this, "bindBuffer");
if (IsContextLost()) if (IsContextLost())
return; return;
if (buffer && !ValidateObject(funcName, *buffer)) if (buffer && !ValidateObject("buffer", *buffer))
return; return;
const auto& slot = ValidateBufferSlot(funcName, target); const auto& slot = ValidateBufferSlot(target);
if (!slot) if (!slot)
return; return;
if (buffer && !buffer->ValidateCanBindToTarget(funcName, target)) if (buffer && !buffer->ValidateCanBindToTarget(target))
return; return;
gl->fBindBuffer(target, buffer ? buffer->mGLName : 0); gl->fBindBuffer(target, buffer ? buffer->mGLName : 0);
@ -167,25 +164,23 @@ WebGLContext::BindBuffer(GLenum target, WebGLBuffer* buffer)
//////////////////////////////////////// ////////////////////////////////////////
bool bool
WebGLContext::ValidateIndexedBufferBinding(const char* funcName, GLenum target, WebGLContext::ValidateIndexedBufferBinding(GLenum target, GLuint index,
GLuint index,
WebGLRefPtr<WebGLBuffer>** const out_genericBinding, WebGLRefPtr<WebGLBuffer>** const out_genericBinding,
IndexedBufferBinding** const out_indexedBinding) IndexedBufferBinding** const out_indexedBinding)
{ {
*out_genericBinding = ValidateBufferSlot(funcName, target); *out_genericBinding = ValidateBufferSlot(target);
if (!*out_genericBinding) if (!*out_genericBinding)
return false; return false;
*out_indexedBinding = ValidateIndexedBufferSlot(funcName, target, index); *out_indexedBinding = ValidateIndexedBufferSlot(target, index);
if (!*out_indexedBinding) if (!*out_indexedBinding)
return false; return false;
if (target == LOCAL_GL_TRANSFORM_FEEDBACK_BUFFER && if (target == LOCAL_GL_TRANSFORM_FEEDBACK_BUFFER &&
mBoundTransformFeedback->mIsActive) mBoundTransformFeedback->mIsActive)
{ {
ErrorInvalidOperation("%s: Cannot update indexed buffer bindings on active" ErrorInvalidOperation("Cannot update indexed buffer bindings on active"
" transform feedback objects.", " transform feedback objects.");
funcName);
return false; return false;
} }
@ -195,22 +190,22 @@ WebGLContext::ValidateIndexedBufferBinding(const char* funcName, GLenum target,
void void
WebGLContext::BindBufferBase(GLenum target, GLuint index, WebGLBuffer* buffer) WebGLContext::BindBufferBase(GLenum target, GLuint index, WebGLBuffer* buffer)
{ {
const char funcName[] = "bindBufferBase"; const FuncScope funcScope(*this, "bindBufferBase");
if (IsContextLost()) if (IsContextLost())
return; return;
if (buffer && !ValidateObject(funcName, *buffer)) if (buffer && !ValidateObject("buffer", *buffer))
return; return;
WebGLRefPtr<WebGLBuffer>* genericBinding; WebGLRefPtr<WebGLBuffer>* genericBinding;
IndexedBufferBinding* indexedBinding; IndexedBufferBinding* indexedBinding;
if (!ValidateIndexedBufferBinding(funcName, target, index, &genericBinding, if (!ValidateIndexedBufferBinding(target, index, &genericBinding,
&indexedBinding)) &indexedBinding))
{ {
return; return;
} }
if (buffer && !buffer->ValidateCanBindToTarget(funcName, target)) if (buffer && !buffer->ValidateCanBindToTarget(target))
return; return;
//// ////
@ -233,32 +228,32 @@ void
WebGLContext::BindBufferRange(GLenum target, GLuint index, WebGLBuffer* buffer, WebGLContext::BindBufferRange(GLenum target, GLuint index, WebGLBuffer* buffer,
WebGLintptr offset, WebGLsizeiptr size) WebGLintptr offset, WebGLsizeiptr size)
{ {
const char funcName[] = "bindBufferRange"; const FuncScope funcScope(*this, "bindBufferRange");
if (IsContextLost()) if (IsContextLost())
return; return;
if (buffer && !ValidateObject(funcName, *buffer)) if (buffer && !ValidateObject("buffer", *buffer))
return; return;
if (!ValidateNonNegative(funcName, "offset", offset) || if (!ValidateNonNegative("offset", offset) ||
!ValidateNonNegative(funcName, "size", size)) !ValidateNonNegative("size", size))
{ {
return; return;
} }
WebGLRefPtr<WebGLBuffer>* genericBinding; WebGLRefPtr<WebGLBuffer>* genericBinding;
IndexedBufferBinding* indexedBinding; IndexedBufferBinding* indexedBinding;
if (!ValidateIndexedBufferBinding(funcName, target, index, &genericBinding, if (!ValidateIndexedBufferBinding(target, index, &genericBinding,
&indexedBinding)) &indexedBinding))
{ {
return; return;
} }
if (buffer && !buffer->ValidateCanBindToTarget(funcName, target)) if (buffer && !buffer->ValidateCanBindToTarget(target))
return; return;
if (buffer && !size) { if (buffer && !size) {
ErrorInvalidValue("%s: size must be non-zero for non-null buffer.", funcName); ErrorInvalidValue("Size must be non-zero for non-null buffer.");
return; return;
} }
@ -267,8 +262,8 @@ WebGLContext::BindBufferRange(GLenum target, GLuint index, WebGLBuffer* buffer,
switch (target) { switch (target) {
case LOCAL_GL_TRANSFORM_FEEDBACK_BUFFER: case LOCAL_GL_TRANSFORM_FEEDBACK_BUFFER:
if (offset % 4 != 0 || size % 4 != 0) { if (offset % 4 != 0 || size % 4 != 0) {
ErrorInvalidValue("%s: For %s, `offset` and `size` must be multiples of 4.", ErrorInvalidValue("For %s, `offset` and `size` must be multiples of 4.",
funcName, "TRANSFORM_FEEDBACK_BUFFER"); "TRANSFORM_FEEDBACK_BUFFER");
return; return;
} }
break; break;
@ -278,8 +273,8 @@ WebGLContext::BindBufferRange(GLenum target, GLuint index, WebGLBuffer* buffer,
GLuint offsetAlignment = 0; GLuint offsetAlignment = 0;
gl->GetUIntegerv(LOCAL_GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT, &offsetAlignment); gl->GetUIntegerv(LOCAL_GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT, &offsetAlignment);
if (offset % offsetAlignment != 0) { if (offset % offsetAlignment != 0) {
ErrorInvalidValue("%s: For %s, `offset` must be a multiple of %s.", ErrorInvalidValue("For %s, `offset` must be a multiple of %s.",
funcName, "UNIFORM_BUFFER", "UNIFORM_BUFFER",
"UNIFORM_BUFFER_OFFSET_ALIGNMENT"); "UNIFORM_BUFFER_OFFSET_ALIGNMENT");
return; return;
} }
@ -319,9 +314,8 @@ void
WebGLContext::BufferDataImpl(GLenum target, size_t dataLen, const uint8_t* data, WebGLContext::BufferDataImpl(GLenum target, size_t dataLen, const uint8_t* data,
GLenum usage) GLenum usage)
{ {
const char funcName[] = "bufferData";
const auto& buffer = ValidateBufferSelection(funcName, target); const auto& buffer = ValidateBufferSelection(target);
if (!buffer) if (!buffer)
return; return;
@ -333,18 +327,18 @@ WebGLContext::BufferDataImpl(GLenum target, size_t dataLen, const uint8_t* data,
void void
WebGLContext::BufferData(GLenum target, WebGLsizeiptr size, GLenum usage) WebGLContext::BufferData(GLenum target, WebGLsizeiptr size, GLenum usage)
{ {
const char funcName[] = "bufferData"; const FuncScope funcScope(*this, "bufferData");
if (IsContextLost()) if (IsContextLost())
return; return;
if (!ValidateNonNegative(funcName, "size", size)) if (!ValidateNonNegative("size", size))
return; return;
//// ////
const UniqueBuffer zeroBuffer(calloc(size, 1)); const UniqueBuffer zeroBuffer(calloc(size, 1));
if (!zeroBuffer) if (!zeroBuffer)
return ErrorOutOfMemory("%s: Failed to allocate zeros.", funcName); return ErrorOutOfMemory("Failed to allocate zeros.");
BufferDataImpl(target, size_t(size), (const uint8_t*)zeroBuffer.get(), usage); BufferDataImpl(target, size_t(size), (const uint8_t*)zeroBuffer.get(), usage);
} }
@ -353,10 +347,11 @@ void
WebGLContext::BufferData(GLenum target, const dom::Nullable<dom::ArrayBuffer>& maybeSrc, WebGLContext::BufferData(GLenum target, const dom::Nullable<dom::ArrayBuffer>& maybeSrc,
GLenum usage) GLenum usage)
{ {
const FuncScope funcScope(*this, "bufferData");
if (IsContextLost()) if (IsContextLost())
return; return;
if (!ValidateNonNull("bufferData", maybeSrc)) if (!ValidateNonNull("src", maybeSrc))
return; return;
const auto& src = maybeSrc.Value(); const auto& src = maybeSrc.Value();
@ -368,13 +363,13 @@ void
WebGLContext::BufferData(GLenum target, const dom::ArrayBufferView& src, GLenum usage, WebGLContext::BufferData(GLenum target, const dom::ArrayBufferView& src, GLenum usage,
GLuint srcElemOffset, GLuint srcElemCountOverride) GLuint srcElemOffset, GLuint srcElemCountOverride)
{ {
const char funcName[] = "bufferData"; const FuncScope funcScope(*this, "bufferData");
if (IsContextLost()) if (IsContextLost())
return; return;
uint8_t* bytes; uint8_t* bytes;
size_t byteLen; size_t byteLen;
if (!ValidateArrayBufferView(funcName, src, srcElemOffset, srcElemCountOverride, if (!ValidateArrayBufferView(src, srcElemOffset, srcElemCountOverride,
&bytes, &byteLen)) &bytes, &byteLen))
{ {
return; return;
@ -389,12 +384,12 @@ void
WebGLContext::BufferSubDataImpl(GLenum target, WebGLsizeiptr dstByteOffset, WebGLContext::BufferSubDataImpl(GLenum target, WebGLsizeiptr dstByteOffset,
size_t dataLen, const uint8_t* data) size_t dataLen, const uint8_t* data)
{ {
const char funcName[] = "bufferSubData"; const FuncScope funcScope(*this, "bufferSubData");
if (!ValidateNonNegative(funcName, "byteOffset", dstByteOffset)) if (!ValidateNonNegative("byteOffset", dstByteOffset))
return; return;
const auto& buffer = ValidateBufferSelection(funcName, target); const auto& buffer = ValidateBufferSelection(target);
if (!buffer) if (!buffer)
return; return;
@ -407,6 +402,7 @@ void
WebGLContext::BufferSubData(GLenum target, WebGLsizeiptr dstByteOffset, WebGLContext::BufferSubData(GLenum target, WebGLsizeiptr dstByteOffset,
const dom::ArrayBuffer& src) const dom::ArrayBuffer& src)
{ {
const FuncScope funcScope(*this, "bufferSubData");
if (IsContextLost()) if (IsContextLost())
return; return;
@ -420,13 +416,13 @@ WebGLContext::BufferSubData(GLenum target, WebGLsizeiptr dstByteOffset,
const dom::ArrayBufferView& src, GLuint srcElemOffset, const dom::ArrayBufferView& src, GLuint srcElemOffset,
GLuint srcElemCountOverride) GLuint srcElemCountOverride)
{ {
const char funcName[] = "bufferSubData"; const FuncScope funcScope(*this, "bufferSubData");
if (IsContextLost()) if (IsContextLost())
return; return;
uint8_t* bytes; uint8_t* bytes;
size_t byteLen; size_t byteLen;
if (!ValidateArrayBufferView(funcName, src, srcElemOffset, srcElemCountOverride, if (!ValidateArrayBufferView(src, srcElemOffset, srcElemCountOverride,
&bytes, &byteLen)) &bytes, &byteLen))
{ {
return; return;
@ -440,6 +436,7 @@ WebGLContext::BufferSubData(GLenum target, WebGLsizeiptr dstByteOffset,
already_AddRefed<WebGLBuffer> already_AddRefed<WebGLBuffer>
WebGLContext::CreateBuffer() WebGLContext::CreateBuffer()
{ {
const FuncScope funcScope(*this, "createBuffer");
if (IsContextLost()) if (IsContextLost())
return nullptr; return nullptr;
@ -453,7 +450,8 @@ WebGLContext::CreateBuffer()
void void
WebGLContext::DeleteBuffer(WebGLBuffer* buffer) WebGLContext::DeleteBuffer(WebGLBuffer* buffer)
{ {
if (!ValidateDeleteObject("deleteBuffer", buffer)) const FuncScope funcScope(*this, "deleteBuffer");
if (!ValidateDeleteObject(buffer))
return; return;
//// ////
@ -498,13 +496,4 @@ WebGLContext::DeleteBuffer(WebGLBuffer* buffer)
buffer->RequestDelete(); buffer->RequestDelete();
} }
bool
WebGLContext::IsBuffer(WebGLBuffer* buffer)
{
if (!ValidateIsObject("isBuffer", buffer))
return false;
return gl->fIsBuffer(buffer->mGLName);
}
} // namespace mozilla } // namespace mozilla

Просмотреть файл

@ -43,13 +43,12 @@ class ScopedResolveTexturesForDraw
std::vector<TexRebindRequest> mRebindRequests; std::vector<TexRebindRequest> mRebindRequests;
public: public:
ScopedResolveTexturesForDraw(WebGLContext* webgl, const char* funcName, ScopedResolveTexturesForDraw(WebGLContext* webgl, bool* const out_error);
bool* const out_error);
~ScopedResolveTexturesForDraw(); ~ScopedResolveTexturesForDraw();
}; };
bool bool
WebGLTexture::IsFeedback(WebGLContext* webgl, const char* funcName, uint32_t texUnit, WebGLTexture::IsFeedback(WebGLContext* webgl, uint32_t texUnit,
const std::vector<const WebGLFBAttachPoint*>& fbAttachments) const const std::vector<const WebGLFBAttachPoint*>& fbAttachments) const
{ {
auto itr = fbAttachments.cbegin(); auto itr = fbAttachments.cbegin();
@ -81,10 +80,10 @@ WebGLTexture::IsFeedback(WebGLContext* webgl, const char* funcName, uint32_t tex
const auto dstLevel = attach->MipLevel(); const auto dstLevel = attach->MipLevel();
if (minLevel <= dstLevel && dstLevel <= maxLevel) { if (minLevel <= dstLevel && dstLevel <= maxLevel) {
webgl->ErrorInvalidOperation("%s: Feedback loop detected between tex target" webgl->ErrorInvalidOperation("Feedback loop detected between tex target"
" 0x%04x, tex unit %u, levels %u-%u; and" " 0x%04x, tex unit %u, levels %u-%u; and"
" framebuffer attachment 0x%04x, level %u.", " framebuffer attachment 0x%04x, level %u.",
funcName, mTarget.get(), texUnit, minLevel, mTarget.get(), texUnit, minLevel,
maxLevel, attach->mAttachmentPoint, dstLevel); maxLevel, attach->mAttachmentPoint, dstLevel);
return true; return true;
} }
@ -94,7 +93,6 @@ WebGLTexture::IsFeedback(WebGLContext* webgl, const char* funcName, uint32_t tex
} }
ScopedResolveTexturesForDraw::ScopedResolveTexturesForDraw(WebGLContext* webgl, ScopedResolveTexturesForDraw::ScopedResolveTexturesForDraw(WebGLContext* webgl,
const char* funcName,
bool* const out_error) bool* const out_error)
: mWebGL(webgl) : mWebGL(webgl)
{ {
@ -120,16 +118,15 @@ ScopedResolveTexturesForDraw::ScopedResolveTexturesForDraw(WebGLContext* webgl,
continue; continue;
if (attachList && if (attachList &&
tex->IsFeedback(mWebGL, funcName, texUnit, *attachList)) tex->IsFeedback(mWebGL, texUnit, *attachList))
{ {
*out_error = true; *out_error = true;
return; return;
} }
FakeBlackType fakeBlack; FakeBlackType fakeBlack;
if (!tex->ResolveForDraw(funcName, texUnit, &fakeBlack)) { if (!tex->ResolveForDraw(texUnit, &fakeBlack)) {
mWebGL->ErrorOutOfMemory("%s: Failed to resolve textures for draw.", mWebGL->ErrorOutOfMemory("Failed to resolve textures for draw.");
funcName);
*out_error = true; *out_error = true;
return; return;
} }
@ -138,8 +135,7 @@ ScopedResolveTexturesForDraw::ScopedResolveTexturesForDraw(WebGLContext* webgl,
continue; continue;
if (!mWebGL->BindFakeBlack(texUnit, tex->Target(), fakeBlack)) { if (!mWebGL->BindFakeBlack(texUnit, tex->Target(), fakeBlack)) {
mWebGL->ErrorOutOfMemory("%s: Failed to create fake black texture.", mWebGL->ErrorOutOfMemory("Failed to create fake black texture.");
funcName);
*out_error = true; *out_error = true;
return; return;
} }
@ -234,7 +230,7 @@ WebGLContext::BindFakeBlack(uint32_t texUnit, TexTarget target, FakeBlackType fa
//////////////////////////////////////// ////////////////////////////////////////
bool bool
WebGLContext::ValidateStencilParamsForDrawCall(const char* const funcName) const WebGLContext::ValidateStencilParamsForDrawCall() const
{ {
const auto stencilBits = [&]() -> uint8_t { const auto stencilBits = [&]() -> uint8_t {
if (!mStencilTestEnabled) if (!mStencilTestEnabled)
@ -264,12 +260,11 @@ WebGLContext::ValidateStencilParamsForDrawCall(const char* const funcName) const
ok &= (fnClamp(mStencilRefFront) == fnClamp(mStencilRefBack)); ok &= (fnClamp(mStencilRefFront) == fnClamp(mStencilRefBack));
if (!ok) { if (!ok) {
ErrorInvalidOperation("%s: Stencil front/back state must effectively match." ErrorInvalidOperation("Stencil front/back state must effectively match."
" (before front/back comparison, WRITEMASK and VALUE_MASK" " (before front/back comparison, WRITEMASK and VALUE_MASK"
" are masked with (2^s)-1, and REF is clamped to" " are masked with (2^s)-1, and REF is clamped to"
" [0, (2^s)-1], where `s` is the number of enabled stencil" " [0, (2^s)-1], where `s` is the number of enabled stencil"
" bits in the draw framebuffer)", " bits in the draw framebuffer)");
funcName);
} }
return ok; return ok;
} }
@ -287,22 +282,33 @@ DoSetsIntersect(const std::set<T>& a, const std::set<T>& b)
} }
const webgl::CachedDrawFetchLimits* const webgl::CachedDrawFetchLimits*
ValidateDraw(WebGLContext* const webgl, const char* const funcName, const GLenum mode, ValidateDraw(WebGLContext* const webgl, const GLenum mode,
const uint32_t instanceCount) const uint32_t instanceCount)
{ {
MOZ_ASSERT(webgl->gl->IsCurrent()); MOZ_ASSERT(webgl->gl->IsCurrent());
if (!webgl->BindCurFBForDraw(funcName)) if (!webgl->BindCurFBForDraw())
return nullptr; return nullptr;
if (!webgl->ValidateDrawModeEnum(mode, funcName)) switch (mode) {
case LOCAL_GL_TRIANGLES:
case LOCAL_GL_TRIANGLE_STRIP:
case LOCAL_GL_TRIANGLE_FAN:
case LOCAL_GL_POINTS:
case LOCAL_GL_LINE_STRIP:
case LOCAL_GL_LINE_LOOP:
case LOCAL_GL_LINES:
break;
default:
webgl->ErrorInvalidEnumInfo("mode", mode);
return nullptr; return nullptr;
}
if (!webgl->ValidateStencilParamsForDrawCall(funcName)) if (!webgl->ValidateStencilParamsForDrawCall())
return nullptr; return nullptr;
if (!webgl->mActiveProgramLinkInfo) { if (!webgl->mActiveProgramLinkInfo) {
webgl->ErrorInvalidOperation("%s: The current program is not linked.", funcName); webgl->ErrorInvalidOperation("The current program is not linked.");
return nullptr; return nullptr;
} }
const auto& linkInfo = webgl->mActiveProgramLinkInfo; const auto& linkInfo = webgl->mActiveProgramLinkInfo;
@ -314,23 +320,20 @@ ValidateDraw(WebGLContext* const webgl, const char* const funcName, const GLenum
const auto& dataSize = cur->mDataSize; const auto& dataSize = cur->mDataSize;
const auto& binding = cur->mBinding; const auto& binding = cur->mBinding;
if (!binding) { if (!binding) {
webgl->ErrorInvalidOperation("%s: Buffer for uniform block is null.", webgl->ErrorInvalidOperation("Buffer for uniform block is null.");
funcName);
return nullptr; return nullptr;
} }
const auto availByteCount = binding->ByteCount(); const auto availByteCount = binding->ByteCount();
if (dataSize > availByteCount) { if (dataSize > availByteCount) {
webgl->ErrorInvalidOperation("%s: Buffer for uniform block is smaller" webgl->ErrorInvalidOperation("Buffer for uniform block is smaller"
" than UNIFORM_BLOCK_DATA_SIZE.", " than UNIFORM_BLOCK_DATA_SIZE.");
funcName);
return nullptr; return nullptr;
} }
if (binding->mBufferBinding->IsBoundForTF()) { if (binding->mBufferBinding->IsBoundForTF()) {
webgl->ErrorInvalidOperation("%s: Buffer for uniform block is bound or" webgl->ErrorInvalidOperation("Buffer for uniform block is bound or"
" in use for transform feedback.", " in use for transform feedback.");
funcName);
return nullptr; return nullptr;
} }
} }
@ -356,9 +359,9 @@ ValidateDraw(WebGLContext* const webgl, const char* const funcName, const GLenum
for (uint32_t i = 0; i < numUsed; ++i) { for (uint32_t i = 0; i < numUsed; ++i) {
const auto& buffer = tfo->mIndexedBindings[i].mBufferBinding; const auto& buffer = tfo->mIndexedBindings[i].mBufferBinding;
if (buffer->IsBoundForNonTF()) { if (buffer->IsBoundForNonTF()) {
webgl->ErrorInvalidOperation("%s: Transform feedback varying %u's buffer" webgl->ErrorInvalidOperation("Transform feedback varying %u's buffer"
" is bound for non-transform-feedback.", " is bound for non-transform-feedback.",
funcName, i); i);
return nullptr; return nullptr;
} }
@ -370,14 +373,14 @@ ValidateDraw(WebGLContext* const webgl, const char* const funcName, const GLenum
// - // -
const auto fetchLimits = linkInfo->GetDrawFetchLimits(funcName); const auto fetchLimits = linkInfo->GetDrawFetchLimits();
if (!fetchLimits) if (!fetchLimits)
return nullptr; return nullptr;
if (instanceCount > fetchLimits->maxInstances) { if (instanceCount > fetchLimits->maxInstances) {
webgl->ErrorInvalidOperation("%s: Instance fetch requires %u, but attribs only" webgl->ErrorInvalidOperation("Instance fetch requires %u, but attribs only"
" supply %u.", " supply %u.",
funcName, instanceCount, instanceCount,
uint32_t(fetchLimits->maxInstances)); uint32_t(fetchLimits->maxInstances));
return nullptr; return nullptr;
} }
@ -397,13 +400,13 @@ class ScopedFakeVertexAttrib0 final
bool mDidFake = false; bool mDidFake = false;
public: public:
ScopedFakeVertexAttrib0(WebGLContext* const webgl, const char* const funcName, ScopedFakeVertexAttrib0(WebGLContext* const webgl,
const uint64_t vertexCount, bool* const out_error) const uint64_t vertexCount, bool* const out_error)
: mWebGL(webgl) : mWebGL(webgl)
{ {
*out_error = false; *out_error = false;
if (!mWebGL->DoFakeVertexAttrib0(funcName, vertexCount)) { if (!mWebGL->DoFakeVertexAttrib0(vertexCount)) {
*out_error = true; *out_error = true;
return; return;
} }
@ -450,7 +453,7 @@ class ScopedDrawWithTransformFeedback final
uint32_t mUsedVerts; uint32_t mUsedVerts;
public: public:
ScopedDrawWithTransformFeedback(WebGLContext* webgl, const char* funcName, ScopedDrawWithTransformFeedback(WebGLContext* webgl,
GLenum mode, uint32_t vertCount, GLenum mode, uint32_t vertCount,
uint32_t instanceCount, bool* const out_error) uint32_t instanceCount, bool* const out_error)
: mWebGL(webgl) : mWebGL(webgl)
@ -465,10 +468,9 @@ public:
return; return;
if (mode != mTFO->mActive_PrimMode) { if (mode != mTFO->mActive_PrimMode) {
mWebGL->ErrorInvalidOperation("%s: Drawing with transform feedback requires" mWebGL->ErrorInvalidOperation("Drawing with transform feedback requires"
" `mode` to match BeginTransformFeedback's" " `mode` to match BeginTransformFeedback's"
" `primitiveMode`.", " `primitiveMode`.");
funcName);
*out_error = true; *out_error = true;
return; return;
} }
@ -480,9 +482,8 @@ public:
if (!usedVerts.isValid() || if (!usedVerts.isValid() ||
usedVerts.value() > remainingCapacity) usedVerts.value() > remainingCapacity)
{ {
mWebGL->ErrorInvalidOperation("%s: Insufficient buffer capacity remaining for" mWebGL->ErrorInvalidOperation("Insufficient buffer capacity remaining for"
" transform feedback.", " transform feedback.");
funcName);
*out_error = true; *out_error = true;
return; return;
} }
@ -509,7 +510,7 @@ HasInstancedDrawing(const WebGLContext& webgl)
void void
WebGLContext::DrawArraysInstanced(GLenum mode, GLint first, GLsizei vertCount, WebGLContext::DrawArraysInstanced(GLenum mode, GLint first, GLsizei vertCount,
GLsizei instanceCount, const char* const funcName) GLsizei instanceCount)
{ {
AUTO_PROFILER_LABEL("WebGLContext::DrawArraysInstanced", GRAPHICS); AUTO_PROFILER_LABEL("WebGLContext::DrawArraysInstanced", GRAPHICS);
if (IsContextLost()) if (IsContextLost())
@ -518,9 +519,9 @@ WebGLContext::DrawArraysInstanced(GLenum mode, GLint first, GLsizei vertCount,
// - // -
if (!ValidateNonNegative(funcName, "first", first) || if (!ValidateNonNegative("first", first) ||
!ValidateNonNegative(funcName, "vertCount", vertCount) || !ValidateNonNegative("vertCount", vertCount) ||
!ValidateNonNegative(funcName, "instanceCount", instanceCount)) !ValidateNonNegative("instanceCount", instanceCount))
{ {
return; return;
} }
@ -537,7 +538,7 @@ WebGLContext::DrawArraysInstanced(GLenum mode, GLint first, GLsizei vertCount,
// - // -
const auto fetchLimits = ValidateDraw(this, funcName, mode, instanceCount); const auto fetchLimits = ValidateDraw(this, mode, instanceCount);
if (!fetchLimits) if (!fetchLimits)
return; return;
@ -545,7 +546,7 @@ WebGLContext::DrawArraysInstanced(GLenum mode, GLint first, GLsizei vertCount,
const auto totalVertCount_safe = CheckedInt<uint32_t>(first) + vertCount; const auto totalVertCount_safe = CheckedInt<uint32_t>(first) + vertCount;
if (!totalVertCount_safe.isValid()) { if (!totalVertCount_safe.isValid()) {
ErrorOutOfMemory("%s: `first+vertCount` out of range.", funcName); ErrorOutOfMemory("`first+vertCount` out of range.");
return; return;
} }
auto totalVertCount = totalVertCount_safe.value(); auto totalVertCount = totalVertCount_safe.value();
@ -553,23 +554,23 @@ WebGLContext::DrawArraysInstanced(GLenum mode, GLint first, GLsizei vertCount,
if (vertCount && instanceCount && if (vertCount && instanceCount &&
totalVertCount > fetchLimits->maxVerts) totalVertCount > fetchLimits->maxVerts)
{ {
ErrorInvalidOperation("%s: Vertex fetch requires %u, but attribs only supply %u.", ErrorInvalidOperation("Vertex fetch requires %u, but attribs only supply %u.",
funcName, totalVertCount, uint32_t(fetchLimits->maxVerts)); totalVertCount, uint32_t(fetchLimits->maxVerts));
return; return;
} }
// - // -
bool error = false; bool error = false;
const ScopedFakeVertexAttrib0 attrib0(this, funcName, totalVertCount, &error); const ScopedFakeVertexAttrib0 attrib0(this, totalVertCount, &error);
if (error) if (error)
return; return;
const ScopedResolveTexturesForDraw scopedResolve(this, funcName, &error); const ScopedResolveTexturesForDraw scopedResolve(this, &error);
if (error) if (error)
return; return;
const ScopedDrawWithTransformFeedback scopedTF(this, funcName, mode, vertCount, const ScopedDrawWithTransformFeedback scopedTF(this, mode, vertCount,
instanceCount, &error); instanceCount, &error);
if (error) if (error)
return; return;
@ -587,14 +588,14 @@ WebGLContext::DrawArraysInstanced(GLenum mode, GLint first, GLsizei vertCount,
} }
} }
Draw_cleanup(funcName); Draw_cleanup();
scopedTF.Advance(); scopedTF.Advance();
} }
//////////////////////////////////////// ////////////////////////////////////////
WebGLBuffer* WebGLBuffer*
WebGLContext::DrawElements_check(const char* const funcName, const GLsizei rawIndexCount, WebGLContext::DrawElements_check(const GLsizei rawIndexCount,
const GLenum type, const WebGLintptr byteOffset, const GLenum type, const WebGLintptr byteOffset,
const GLsizei instanceCount) const GLsizei instanceCount)
{ {
@ -602,15 +603,14 @@ WebGLContext::DrawElements_check(const char* const funcName, const GLsizei rawIn
mBoundTransformFeedback->mIsActive && mBoundTransformFeedback->mIsActive &&
!mBoundTransformFeedback->mIsPaused) !mBoundTransformFeedback->mIsPaused)
{ {
ErrorInvalidOperation("%s: DrawElements* functions are incompatible with" ErrorInvalidOperation("DrawElements* functions are incompatible with"
" transform feedback.", " transform feedback.");
funcName);
return nullptr; return nullptr;
} }
if (!ValidateNonNegative(funcName, "vertCount", rawIndexCount) || if (!ValidateNonNegative("vertCount", rawIndexCount) ||
!ValidateNonNegative(funcName, "byteOffset", byteOffset) || !ValidateNonNegative("byteOffset", byteOffset) ||
!ValidateNonNegative(funcName, "instanceCount", instanceCount)) !ValidateNonNegative("instanceCount", instanceCount))
{ {
return nullptr; return nullptr;
} }
@ -633,12 +633,11 @@ WebGLContext::DrawElements_check(const char* const funcName, const GLsizei rawIn
break; break;
} }
if (!bytesPerIndex) { if (!bytesPerIndex) {
ErrorInvalidEnum("%s: Invalid `type`: 0x%04x", funcName, type); ErrorInvalidEnumInfo("type", type);
return nullptr; return nullptr;
} }
if (byteOffset % bytesPerIndex != 0) { if (byteOffset % bytesPerIndex != 0) {
ErrorInvalidOperation("%s: `byteOffset` must be a multiple of the size of `type`", ErrorInvalidOperation("`byteOffset` must be a multiple of the size of `type`");
funcName);
return nullptr; return nullptr;
} }
@ -660,7 +659,7 @@ WebGLContext::DrawElements_check(const char* const funcName, const GLsizei rawIn
const auto& indexBuffer = mBoundVertexArray->mElementArrayBuffer; const auto& indexBuffer = mBoundVertexArray->mElementArrayBuffer;
if (!indexBuffer) { if (!indexBuffer) {
ErrorInvalidOperation("%s: Index buffer not bound.", funcName); ErrorInvalidOperation("Index buffer not bound.");
return nullptr; return nullptr;
} }
MOZ_ASSERT(!indexBuffer->IsBoundForTF(), "This should be impossible."); MOZ_ASSERT(!indexBuffer->IsBoundForTF(), "This should be impossible.");
@ -669,7 +668,7 @@ WebGLContext::DrawElements_check(const char* const funcName, const GLsizei rawIn
const auto availIndices = AvailGroups(availBytes, byteOffset, bytesPerIndex, const auto availIndices = AvailGroups(availBytes, byteOffset, bytesPerIndex,
bytesPerIndex); bytesPerIndex);
if (instanceCount && indexCount > availIndices) { if (instanceCount && indexCount > availIndices) {
ErrorInvalidOperation("%s: Index buffer too small.", funcName); ErrorInvalidOperation("Index buffer too small.");
return nullptr; return nullptr;
} }
@ -677,44 +676,43 @@ WebGLContext::DrawElements_check(const char* const funcName, const GLsizei rawIn
} }
static void static void
HandleDrawElementsErrors(WebGLContext* webgl, const char* funcName, HandleDrawElementsErrors(WebGLContext* webgl,
gl::GLContext::LocalErrorScope& errorScope) gl::GLContext::LocalErrorScope& errorScope)
{ {
const auto err = errorScope.GetError(); const auto err = errorScope.GetError();
if (err == LOCAL_GL_INVALID_OPERATION) { if (err == LOCAL_GL_INVALID_OPERATION) {
webgl->ErrorInvalidOperation("%s: Driver rejected indexed draw call, possibly" webgl->ErrorInvalidOperation("Driver rejected indexed draw call, possibly"
" due to out-of-bounds indices.", funcName); " due to out-of-bounds indices.");
return; return;
} }
MOZ_ASSERT(!err); MOZ_ASSERT(!err);
if (err) { if (err) {
webgl->ErrorImplementationBug("%s: Unexpected driver error during indexed draw" webgl->ErrorImplementationBug("Unexpected driver error during indexed draw"
" call. Please file a bug.", " call. Please file a bug.");
funcName);
return; return;
} }
} }
void void
WebGLContext::DrawElementsInstanced(GLenum mode, GLsizei indexCount, GLenum type, WebGLContext::DrawElementsInstanced(GLenum mode, GLsizei indexCount, GLenum type,
WebGLintptr byteOffset, GLsizei instanceCount, WebGLintptr byteOffset, GLsizei instanceCount)
const char* const funcName)
{ {
const FuncScope funcScope(*this, "drawElementsInstanced");
AUTO_PROFILER_LABEL("WebGLContext::DrawElementsInstanced", GRAPHICS); AUTO_PROFILER_LABEL("WebGLContext::DrawElementsInstanced", GRAPHICS);
if (IsContextLost()) if (IsContextLost())
return; return;
const gl::GLContext::TlsScope inTls(gl); const gl::GLContext::TlsScope inTls(gl);
const auto indexBuffer = DrawElements_check(funcName, indexCount, type, byteOffset, const auto indexBuffer = DrawElements_check(indexCount, type, byteOffset,
instanceCount); instanceCount);
if (!indexBuffer) if (!indexBuffer)
return; return;
// - // -
const auto fetchLimits = ValidateDraw(this, funcName, mode, instanceCount); const auto fetchLimits = ValidateDraw(this, mode, instanceCount);
if (!fetchLimits) if (!fetchLimits)
return; return;
@ -760,9 +758,9 @@ WebGLContext::DrawElementsInstanced(GLenum mode, GLsizei indexCount, GLenum type
return maxVertId < fetchLimits->maxVerts; return maxVertId < fetchLimits->maxVerts;
}(); }();
if (!isFetchValid) { if (!isFetchValid) {
ErrorInvalidOperation("%s: Indexed vertex fetch requires %u vertices, but" ErrorInvalidOperation("Indexed vertex fetch requires %u vertices, but"
" attribs only supply %u.", " attribs only supply %u.",
funcName, maxVertId+1, uint32_t(fetchLimits->maxVerts)); maxVertId+1, uint32_t(fetchLimits->maxVerts));
return; return;
} }
} }
@ -770,11 +768,11 @@ WebGLContext::DrawElementsInstanced(GLenum mode, GLsizei indexCount, GLenum type
// - // -
bool error = false; bool error = false;
const ScopedFakeVertexAttrib0 attrib0(this, funcName, fakeVertCount, &error); const ScopedFakeVertexAttrib0 attrib0(this, fakeVertCount, &error);
if (error) if (error)
return; return;
const ScopedResolveTexturesForDraw scopedResolve(this, funcName, &error); const ScopedResolveTexturesForDraw scopedResolve(this, &error);
if (error) if (error)
return; return;
@ -812,18 +810,18 @@ WebGLContext::DrawElementsInstanced(GLenum mode, GLsizei indexCount, GLenum type
} }
if (errorScope) { if (errorScope) {
HandleDrawElementsErrors(this, funcName, *errorScope); HandleDrawElementsErrors(this, *errorScope);
} }
} }
} }
Draw_cleanup(funcName); Draw_cleanup();
} }
//////////////////////////////////////// ////////////////////////////////////////
void void
WebGLContext::Draw_cleanup(const char* funcName) WebGLContext::Draw_cleanup()
{ {
if (gl->WorkAroundDriverBugs()) { if (gl->WorkAroundDriverBugs()) {
if (gl->Renderer() == gl::GLRenderer::Tegra) { if (gl->Renderer() == gl::GLRenderer::Tegra) {
@ -858,9 +856,8 @@ WebGLContext::Draw_cleanup(const char* funcName)
mViewportHeight > int32_t(destHeight)) mViewportHeight > int32_t(destHeight))
{ {
if (!mAlreadyWarnedAboutViewportLargerThanDest) { if (!mAlreadyWarnedAboutViewportLargerThanDest) {
GenerateWarning("%s: Drawing to a destination rect smaller than the viewport" GenerateWarning("Drawing to a destination rect smaller than the viewport"
" rect. (This warning will only be given once)", " rect. (This warning will only be given once)");
funcName);
mAlreadyWarnedAboutViewportLargerThanDest = true; mAlreadyWarnedAboutViewportLargerThanDest = true;
} }
} }
@ -895,7 +892,7 @@ WebGLContext::WhatDoesVertexAttrib0Need() const
} }
bool bool
WebGLContext::DoFakeVertexAttrib0(const char* const funcName, const uint64_t vertexCount) WebGLContext::DoFakeVertexAttrib0(const uint64_t vertexCount)
{ {
const auto whatDoesAttrib0Need = WhatDoesVertexAttrib0Need(); const auto whatDoesAttrib0Need = WhatDoesVertexAttrib0Need();
if (MOZ_LIKELY(whatDoesAttrib0Need == WebGLVertexAttrib0Status::Default)) if (MOZ_LIKELY(whatDoesAttrib0Need == WebGLVertexAttrib0Status::Default))
@ -971,8 +968,7 @@ WebGLContext::DoFakeVertexAttrib0(const char* const funcName, const uint64_t ver
const UniqueBuffer data(malloc(dataSize)); const UniqueBuffer data(malloc(dataSize));
if (!data) { if (!data) {
ErrorOutOfMemory("%s: Failed to allocate fake vertex attrib 0 array.", ErrorOutOfMemory("Failed to allocate fake vertex attrib 0 array.");
funcName);
return false; return false;
} }
auto itr = (uint8_t*)data.get(); auto itr = (uint8_t*)data.get();
@ -989,7 +985,7 @@ WebGLContext::DoFakeVertexAttrib0(const char* const funcName, const uint64_t ver
const auto err = errorScope.GetError(); const auto err = errorScope.GetError();
if (err) { if (err) {
ErrorOutOfMemory("%s: Failed to upload fake vertex attrib 0 data.", funcName); ErrorOutOfMemory("Failed to upload fake vertex attrib 0 data.");
return false; return false;
} }
} }

Просмотреть файл

@ -262,7 +262,7 @@ WebGLContext::GetExtension(JSContext* cx,
ErrorResult& rv) ErrorResult& rv)
{ {
retval.set(nullptr); retval.set(nullptr);
const FuncScope funcScope(*this, "getExtension");
if (IsContextLost()) if (IsContextLost())
return; return;
@ -430,6 +430,7 @@ WebGLContext::GetSupportedExtensions(dom::Nullable< nsTArray<nsString> >& retval
dom::CallerType callerType) dom::CallerType callerType)
{ {
retval.SetNull(); retval.SetNull();
const FuncScope funcScope(*this, "getSupportedExtensions");
if (IsContextLost()) if (IsContextLost())
return; return;

Просмотреть файл

@ -15,14 +15,13 @@ namespace mozilla {
void void
WebGLContext::Clear(GLbitfield mask) WebGLContext::Clear(GLbitfield mask)
{ {
const char funcName[] = "clear"; const FuncScope funcScope(*this, "clear");
if (IsContextLost()) if (IsContextLost())
return; return;
uint32_t m = mask & (LOCAL_GL_COLOR_BUFFER_BIT | LOCAL_GL_DEPTH_BUFFER_BIT | LOCAL_GL_STENCIL_BUFFER_BIT); uint32_t m = mask & (LOCAL_GL_COLOR_BUFFER_BIT | LOCAL_GL_DEPTH_BUFFER_BIT | LOCAL_GL_STENCIL_BUFFER_BIT);
if (mask != m) if (mask != m)
return ErrorInvalidValue("%s: invalid mask bits", funcName); return ErrorInvalidValue("Invalid mask bits.");
if (mask == 0) { if (mask == 0) {
GenerateWarning("Calling gl.clear(0) has no effect."); GenerateWarning("Calling gl.clear(0) has no effect.");
@ -43,16 +42,15 @@ WebGLContext::Clear(GLbitfield mask)
break; break;
default: default:
ErrorInvalidOperation("%s: Color draw buffers must be floating-point" ErrorInvalidOperation("Color draw buffers must be floating-point"
" or fixed-point. (normalized (u)ints)", " or fixed-point. (normalized (u)ints)");
funcName);
return; return;
} }
} }
} }
} }
if (!BindCurFBForDraw(funcName)) if (!BindCurFBForDraw())
return; return;
auto driverMask = mask; auto driverMask = mask;
@ -84,6 +82,7 @@ GLClampFloat(GLfloat val)
void void
WebGLContext::ClearColor(GLfloat r, GLfloat g, GLfloat b, GLfloat a) WebGLContext::ClearColor(GLfloat r, GLfloat g, GLfloat b, GLfloat a)
{ {
const FuncScope funcScope(*this, "clearColor");
if (IsContextLost()) if (IsContextLost())
return; return;
@ -108,6 +107,7 @@ WebGLContext::ClearColor(GLfloat r, GLfloat g, GLfloat b, GLfloat a)
void void
WebGLContext::ClearDepth(GLclampf v) WebGLContext::ClearDepth(GLclampf v)
{ {
const FuncScope funcScope(*this, "clearDepth");
if (IsContextLost()) if (IsContextLost())
return; return;
@ -118,6 +118,7 @@ WebGLContext::ClearDepth(GLclampf v)
void void
WebGLContext::ClearStencil(GLint v) WebGLContext::ClearStencil(GLint v)
{ {
const FuncScope funcScope(*this, "clearStencil");
if (IsContextLost()) if (IsContextLost())
return; return;
@ -128,6 +129,7 @@ WebGLContext::ClearStencil(GLint v)
void void
WebGLContext::ColorMask(WebGLboolean r, WebGLboolean g, WebGLboolean b, WebGLboolean a) WebGLContext::ColorMask(WebGLboolean r, WebGLboolean g, WebGLboolean b, WebGLboolean a)
{ {
const FuncScope funcScope(*this, "colorMask");
if (IsContextLost()) if (IsContextLost())
return; return;
@ -140,6 +142,7 @@ WebGLContext::ColorMask(WebGLboolean r, WebGLboolean g, WebGLboolean b, WebGLboo
void void
WebGLContext::DepthMask(WebGLboolean b) WebGLContext::DepthMask(WebGLboolean b)
{ {
const FuncScope funcScope(*this, "depthMask");
if (IsContextLost()) if (IsContextLost())
return; return;
@ -150,12 +153,12 @@ WebGLContext::DepthMask(WebGLboolean b)
void void
WebGLContext::DrawBuffers(const dom::Sequence<GLenum>& buffers) WebGLContext::DrawBuffers(const dom::Sequence<GLenum>& buffers)
{ {
const char funcName[] = "drawBuffers"; const FuncScope funcScope(*this, "drawBuffers");
if (IsContextLost()) if (IsContextLost())
return; return;
if (mBoundDrawFramebuffer) { if (mBoundDrawFramebuffer) {
mBoundDrawFramebuffer->DrawBuffers(funcName, buffers); mBoundDrawFramebuffer->DrawBuffers(buffers);
return; return;
} }
@ -165,9 +168,8 @@ WebGLContext::DrawBuffers(const dom::Sequence<GLenum>& buffers)
// constant other than BACK and NONE, or with a value of `n` other than 1, the // constant other than BACK and NONE, or with a value of `n` other than 1, the
// error INVALID_OPERATION is generated." // error INVALID_OPERATION is generated."
if (buffers.Length() != 1) { if (buffers.Length() != 1) {
ErrorInvalidOperation("%s: For the default framebuffer, `buffers` must have a" ErrorInvalidOperation("For the default framebuffer, `buffers` must have a"
" length of 1.", " length of 1.");
funcName);
return; return;
} }
@ -177,9 +179,8 @@ WebGLContext::DrawBuffers(const dom::Sequence<GLenum>& buffers)
break; break;
default: default:
ErrorInvalidOperation("%s: For the default framebuffer, `buffers[0]` must be" ErrorInvalidOperation("For the default framebuffer, `buffers[0]` must be"
" BACK or NONE.", " BACK or NONE.");
funcName);
return; return;
} }
@ -190,6 +191,7 @@ WebGLContext::DrawBuffers(const dom::Sequence<GLenum>& buffers)
void void
WebGLContext::StencilMask(GLuint mask) WebGLContext::StencilMask(GLuint mask)
{ {
const FuncScope funcScope(*this, "stencilMask");
if (IsContextLost()) if (IsContextLost())
return; return;
@ -202,10 +204,11 @@ WebGLContext::StencilMask(GLuint mask)
void void
WebGLContext::StencilMaskSeparate(GLenum face, GLuint mask) WebGLContext::StencilMaskSeparate(GLenum face, GLuint mask)
{ {
const FuncScope funcScope(*this, "stencilMaskSeparate");
if (IsContextLost()) if (IsContextLost())
return; return;
if (!ValidateFaceEnum(face, "stencilMaskSeparate: face")) if (!ValidateFaceEnum(face))
return; return;
switch (face) { switch (face) {

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -26,10 +26,11 @@ namespace mozilla {
void void
WebGLContext::SetEnabled(const char* const funcName, const GLenum cap, const bool enabled) WebGLContext::SetEnabled(const char* const funcName, const GLenum cap, const bool enabled)
{ {
const FuncScope funcScope(*this, funcName);
if (IsContextLost()) if (IsContextLost())
return; return;
if (!ValidateCapabilityEnum(cap, funcName)) if (!ValidateCapabilityEnum(cap))
return; return;
const auto& slot = GetStateTrackingSlot(cap); const auto& slot = GetStateTrackingSlot(cap);
@ -77,7 +78,7 @@ WebGLContext::GetStencilBits(GLint* const out_stencilBits) const
JS::Value JS::Value
WebGLContext::GetParameter(JSContext* cx, GLenum pname, ErrorResult& rv) WebGLContext::GetParameter(JSContext* cx, GLenum pname, ErrorResult& rv)
{ {
const char funcName[] = "getParameter"; const FuncScope funcScope(*this, "getParameter");
if (IsContextLost()) if (IsContextLost())
return JS::NullValue(); return JS::NullValue();
@ -247,7 +248,7 @@ WebGLContext::GetParameter(JSContext* cx, GLenum pname, ErrorResult& rv)
case LOCAL_GL_IMPLEMENTATION_COLOR_READ_TYPE: { case LOCAL_GL_IMPLEMENTATION_COLOR_READ_TYPE: {
const webgl::FormatUsageInfo* usage; const webgl::FormatUsageInfo* usage;
uint32_t width, height; uint32_t width, height;
if (!BindCurFBForColorRead(funcName, &usage, &width, &height)) if (!BindCurFBForColorRead(&usage, &width, &height))
return JS::NullValue(); return JS::NullValue();
const auto implPI = ValidImplementationColorReadPI(usage); const auto implPI = ValidImplementationColorReadPI(usage);
@ -282,12 +283,12 @@ WebGLContext::GetParameter(JSContext* cx, GLenum pname, ErrorResult& rv)
const auto& fb = mBoundDrawFramebuffer; const auto& fb = mBoundDrawFramebuffer;
auto samples = [&]() -> Maybe<uint32_t> { auto samples = [&]() -> Maybe<uint32_t> {
if (!fb) { if (!fb) {
if (!EnsureDefaultFB(funcName)) if (!EnsureDefaultFB())
return Nothing(); return Nothing();
return Some(mDefaultFB->mSamples); return Some(mDefaultFB->mSamples);
} }
if (!fb->IsCheckFramebufferStatusComplete(funcName)) if (!fb->IsCheckFramebufferStatusComplete())
return Some(0); return Some(0);
DoBindFB(fb, LOCAL_GL_FRAMEBUFFER); DoBindFB(fb, LOCAL_GL_FRAMEBUFFER);
@ -590,7 +591,7 @@ WebGLContext::GetParameter(JSContext* cx, GLenum pname, ErrorResult& rv)
break; break;
} }
ErrorInvalidEnumInfo("getParameter: parameter", pname); ErrorInvalidEnumInfo("pname", pname);
return JS::NullValue(); return JS::NullValue();
} }
@ -598,6 +599,7 @@ void
WebGLContext::GetParameterIndexed(JSContext* cx, GLenum pname, GLuint index, WebGLContext::GetParameterIndexed(JSContext* cx, GLenum pname, GLuint index,
JS::MutableHandle<JS::Value> retval) JS::MutableHandle<JS::Value> retval)
{ {
const FuncScope funcScope(*this, "getParameterIndexed");
if (IsContextLost()) { if (IsContextLost()) {
retval.setNull(); retval.setNull();
return; return;
@ -607,7 +609,7 @@ WebGLContext::GetParameterIndexed(JSContext* cx, GLenum pname, GLuint index,
case LOCAL_GL_TRANSFORM_FEEDBACK_BUFFER_BINDING: case LOCAL_GL_TRANSFORM_FEEDBACK_BUFFER_BINDING:
{ {
if (index >= mGLMaxTransformFeedbackSeparateAttribs) { if (index >= mGLMaxTransformFeedbackSeparateAttribs) {
ErrorInvalidValue("getParameterIndexed: index should be less than MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS"); ErrorInvalidValue("`index` should be less than MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS");
retval.setNull(); retval.setNull();
return; return;
} }
@ -619,17 +621,18 @@ WebGLContext::GetParameterIndexed(JSContext* cx, GLenum pname, GLuint index,
break; break;
} }
ErrorInvalidEnumInfo("getParameterIndexed: parameter", pname); ErrorInvalidEnumInfo("pname", pname);
retval.setNull(); retval.setNull();
} }
bool bool
WebGLContext::IsEnabled(GLenum cap) WebGLContext::IsEnabled(GLenum cap)
{ {
const FuncScope funcScope(*this, "isEnabled");
if (IsContextLost()) if (IsContextLost())
return false; return false;
if (!ValidateCapabilityEnum(cap, "isEnabled")) if (!ValidateCapabilityEnum(cap))
return false; return false;
const auto& slot = GetStateTrackingSlot(cap); const auto& slot = GetStateTrackingSlot(cap);
@ -640,7 +643,7 @@ WebGLContext::IsEnabled(GLenum cap)
} }
bool bool
WebGLContext::ValidateCapabilityEnum(GLenum cap, const char* info) WebGLContext::ValidateCapabilityEnum(GLenum cap)
{ {
switch (cap) { switch (cap) {
case LOCAL_GL_BLEND: case LOCAL_GL_BLEND:
@ -656,7 +659,7 @@ WebGLContext::ValidateCapabilityEnum(GLenum cap, const char* info)
case LOCAL_GL_RASTERIZER_DISCARD: case LOCAL_GL_RASTERIZER_DISCARD:
return IsWebGL2(); return IsWebGL2();
default: default:
ErrorInvalidEnumInfo(info, cap); ErrorInvalidEnumInfo("cap", cap);
return false; return false;
} }
} }

Просмотреть файл

@ -120,7 +120,7 @@ IsValidTexImageTarget(WebGLContext* webgl, uint8_t funcDims, GLenum rawTexImageT
} }
bool bool
ValidateTexTarget(WebGLContext* webgl, const char* funcName, uint8_t funcDims, ValidateTexTarget(WebGLContext* webgl, uint8_t funcDims,
GLenum rawTexTarget, TexTarget* const out_texTarget, GLenum rawTexTarget, TexTarget* const out_texTarget,
WebGLTexture** const out_tex) WebGLTexture** const out_tex)
{ {
@ -129,13 +129,13 @@ ValidateTexTarget(WebGLContext* webgl, const char* funcName, uint8_t funcDims,
TexTarget texTarget; TexTarget texTarget;
if (!IsValidTexTarget(webgl, funcDims, rawTexTarget, &texTarget)) { if (!IsValidTexTarget(webgl, funcDims, rawTexTarget, &texTarget)) {
webgl->ErrorInvalidEnum("%s: Invalid texTarget.", funcName); webgl->ErrorInvalidEnumInfo("texTarget", rawTexTarget);
return false; return false;
} }
WebGLTexture* tex = webgl->ActiveBoundTextureForTarget(texTarget); WebGLTexture* tex = webgl->ActiveBoundTextureForTarget(texTarget);
if (!tex) { if (!tex) {
webgl->ErrorInvalidOperation("%s: No texture is bound to this target.", funcName); webgl->ErrorInvalidOperation("No texture is bound to this target.");
return false; return false;
} }
@ -145,7 +145,7 @@ ValidateTexTarget(WebGLContext* webgl, const char* funcName, uint8_t funcDims,
} }
bool bool
ValidateTexImageTarget(WebGLContext* webgl, const char* funcName, uint8_t funcDims, ValidateTexImageTarget(WebGLContext* webgl, uint8_t funcDims,
GLenum rawTexImageTarget, TexImageTarget* const out_texImageTarget, GLenum rawTexImageTarget, TexImageTarget* const out_texImageTarget,
WebGLTexture** const out_tex) WebGLTexture** const out_tex)
{ {
@ -154,13 +154,13 @@ ValidateTexImageTarget(WebGLContext* webgl, const char* funcName, uint8_t funcDi
TexImageTarget texImageTarget; TexImageTarget texImageTarget;
if (!IsValidTexImageTarget(webgl, funcDims, rawTexImageTarget, &texImageTarget)) { if (!IsValidTexImageTarget(webgl, funcDims, rawTexImageTarget, &texImageTarget)) {
webgl->ErrorInvalidEnum("%s: Invalid texImageTarget.", funcName); webgl->ErrorInvalidEnumInfo("texImageTarget", rawTexImageTarget);
return false; return false;
} }
WebGLTexture* tex = webgl->ActiveBoundTextureForTexImageTarget(texImageTarget); WebGLTexture* tex = webgl->ActiveBoundTextureForTexImageTarget(texImageTarget);
if (!tex) { if (!tex) {
webgl->ErrorInvalidOperation("%s: No texture is bound to this target.", funcName); webgl->ErrorInvalidOperation("No texture is bound to this target.");
return false; return false;
} }
@ -206,10 +206,11 @@ WebGLContext::InvalidateResolveCacheForTextureWithTexUnit(const GLuint texUnit)
void void
WebGLContext::BindTexture(GLenum rawTarget, WebGLTexture* newTex) WebGLContext::BindTexture(GLenum rawTarget, WebGLTexture* newTex)
{ {
const FuncScope funcScope(*this, "bindTexture");
if (IsContextLost()) if (IsContextLost())
return; return;
if (newTex && !ValidateObject("bindTexture", *newTex)) if (newTex && !ValidateObject("tex", *newTex))
return; return;
// Need to check rawTarget first before comparing against newTex->Target() as // Need to check rawTarget first before comparing against newTex->Target() as
@ -236,7 +237,7 @@ WebGLContext::BindTexture(GLenum rawTarget, WebGLTexture* newTex)
} }
if (!currentTexPtr) { if (!currentTexPtr) {
ErrorInvalidEnumInfo("bindTexture: target", rawTarget); ErrorInvalidEnumInfo("target", rawTarget);
return; return;
} }
@ -254,12 +255,12 @@ WebGLContext::BindTexture(GLenum rawTarget, WebGLTexture* newTex)
void void
WebGLContext::GenerateMipmap(GLenum rawTexTarget) WebGLContext::GenerateMipmap(GLenum rawTexTarget)
{ {
const char funcName[] = "generateMipmap"; const FuncScope funcScope(*this, "generateMipmap");
const uint8_t funcDims = 0; const uint8_t funcDims = 0;
TexTarget texTarget; TexTarget texTarget;
WebGLTexture* tex; WebGLTexture* tex;
if (!ValidateTexTarget(this, funcName, funcDims, rawTexTarget, &texTarget, &tex)) if (!ValidateTexTarget(this, funcDims, rawTexTarget, &texTarget, &tex))
return; return;
tex->GenerateMipmap(texTarget); tex->GenerateMipmap(texTarget);
@ -268,41 +269,32 @@ WebGLContext::GenerateMipmap(GLenum rawTexTarget)
JS::Value JS::Value
WebGLContext::GetTexParameter(GLenum rawTexTarget, GLenum pname) WebGLContext::GetTexParameter(GLenum rawTexTarget, GLenum pname)
{ {
const char funcName[] = "getTexParameter"; const FuncScope funcScope(*this, "getTexParameter");
const uint8_t funcDims = 0; const uint8_t funcDims = 0;
TexTarget texTarget; TexTarget texTarget;
WebGLTexture* tex; WebGLTexture* tex;
if (!ValidateTexTarget(this, funcName, funcDims, rawTexTarget, &texTarget, &tex)) if (!ValidateTexTarget(this, funcDims, rawTexTarget, &texTarget, &tex))
return JS::NullValue(); return JS::NullValue();
if (!IsTexParamValid(pname)) { if (!IsTexParamValid(pname)) {
ErrorInvalidEnumInfo("getTexParameter: pname", pname); ErrorInvalidEnumInfo("pname", pname);
return JS::NullValue(); return JS::NullValue();
} }
return tex->GetTexParameter(texTarget, pname); return tex->GetTexParameter(texTarget, pname);
} }
bool
WebGLContext::IsTexture(WebGLTexture* tex)
{
if (!ValidateIsObject("isTexture", tex))
return false;
return tex->IsTexture();
}
void void
WebGLContext::TexParameter_base(GLenum rawTexTarget, GLenum pname, WebGLContext::TexParameter_base(GLenum rawTexTarget, GLenum pname,
const FloatOrInt& param) const FloatOrInt& param)
{ {
const char funcName[] = "texParameter"; const FuncScope funcScope(*this, "texParameter");
const uint8_t funcDims = 0; const uint8_t funcDims = 0;
TexTarget texTarget; TexTarget texTarget;
WebGLTexture* tex; WebGLTexture* tex;
if (!ValidateTexTarget(this, funcName, funcDims, rawTexTarget, &texTarget, &tex)) if (!ValidateTexTarget(this, funcDims, rawTexTarget, &texTarget, &tex))
return; return;
tex->TexParameter(texTarget, pname, param); tex->TexParameter(texTarget, pname, param);
@ -312,22 +304,22 @@ WebGLContext::TexParameter_base(GLenum rawTexTarget, GLenum pname,
// Uploads // Uploads
void void
WebGLContext::CompressedTexImage(const char* funcName, uint8_t funcDims, GLenum rawTarget, WebGLContext::CompressedTexImage(uint8_t funcDims, GLenum rawTarget,
GLint level, GLenum internalFormat, GLsizei width, GLint level, GLenum internalFormat, GLsizei width,
GLsizei height, GLsizei depth, GLint border, GLsizei height, GLsizei depth, GLint border,
const TexImageSource& src, const Maybe<GLsizei>& expectedImageSize) const TexImageSource& src, const Maybe<GLsizei>& expectedImageSize)
{ {
TexImageTarget target; TexImageTarget target;
WebGLTexture* tex; WebGLTexture* tex;
if (!ValidateTexImageTarget(this, funcName, funcDims, rawTarget, &target, &tex)) if (!ValidateTexImageTarget(this, funcDims, rawTarget, &target, &tex))
return; return;
tex->CompressedTexImage(funcName, target, level, internalFormat, width, height, depth, tex->CompressedTexImage(target, level, internalFormat, width, height, depth,
border, src, expectedImageSize); border, src, expectedImageSize);
} }
void void
WebGLContext::CompressedTexSubImage(const char* funcName, uint8_t funcDims, WebGLContext::CompressedTexSubImage(uint8_t funcDims,
GLenum rawTarget, GLint level, GLint xOffset, GLenum rawTarget, GLint level, GLint xOffset,
GLint yOffset, GLint zOffset, GLsizei width, GLint yOffset, GLint zOffset, GLsizei width,
GLsizei height, GLsizei depth, GLenum unpackFormat, GLsizei height, GLsizei depth, GLenum unpackFormat,
@ -335,10 +327,10 @@ WebGLContext::CompressedTexSubImage(const char* funcName, uint8_t funcDims,
{ {
TexImageTarget target; TexImageTarget target;
WebGLTexture* tex; WebGLTexture* tex;
if (!ValidateTexImageTarget(this, funcName, funcDims, rawTarget, &target, &tex)) if (!ValidateTexImageTarget(this, funcDims, rawTarget, &target, &tex))
return; return;
tex->CompressedTexSubImage(funcName, target, level, xOffset, yOffset, zOffset, width, tex->CompressedTexSubImage(target, level, xOffset, yOffset, zOffset, width,
height, depth, unpackFormat, src, expectedImageSize); height, depth, unpackFormat, src, expectedImageSize);
} }
@ -349,51 +341,51 @@ WebGLContext::CopyTexImage2D(GLenum rawTarget, GLint level, GLenum internalForma
GLint x, GLint y, GLsizei width, GLsizei height, GLint x, GLint y, GLsizei width, GLsizei height,
GLint border) GLint border)
{ {
const char funcName[] = "copyTexImage2D"; const FuncScope funcScope(*this, "copyTexImage2D");
const uint8_t funcDims = 2; const uint8_t funcDims = 2;
TexImageTarget target; TexImageTarget target;
WebGLTexture* tex; WebGLTexture* tex;
if (!ValidateTexImageTarget(this, funcName, funcDims, rawTarget, &target, &tex)) if (!ValidateTexImageTarget(this, funcDims, rawTarget, &target, &tex))
return; return;
tex->CopyTexImage2D(target, level, internalFormat, x, y, width, height, border); tex->CopyTexImage2D(target, level, internalFormat, x, y, width, height, border);
} }
void void
WebGLContext::CopyTexSubImage(const char* funcName, uint8_t funcDims, GLenum rawTarget, WebGLContext::CopyTexSubImage(uint8_t funcDims, GLenum rawTarget,
GLint level, GLint xOffset, GLint yOffset, GLint zOffset, GLint level, GLint xOffset, GLint yOffset, GLint zOffset,
GLint x, GLint y, GLsizei width, GLsizei height) GLint x, GLint y, GLsizei width, GLsizei height)
{ {
TexImageTarget target; TexImageTarget target;
WebGLTexture* tex; WebGLTexture* tex;
if (!ValidateTexImageTarget(this, funcName, funcDims, rawTarget, &target, &tex)) if (!ValidateTexImageTarget(this, funcDims, rawTarget, &target, &tex))
return; return;
tex->CopyTexSubImage(funcName, target, level, xOffset, yOffset, zOffset, x, y, width, tex->CopyTexSubImage(target, level, xOffset, yOffset, zOffset, x, y, width,
height); height);
} }
//// ////
void void
WebGLContext::TexImage(const char* funcName, uint8_t funcDims, GLenum rawTarget, WebGLContext::TexImage(uint8_t funcDims, GLenum rawTarget,
GLint level, GLenum internalFormat, GLsizei width, GLsizei height, GLint level, GLenum internalFormat, GLsizei width, GLsizei height,
GLsizei depth, GLint border, GLenum unpackFormat, GLsizei depth, GLint border, GLenum unpackFormat,
GLenum unpackType, const TexImageSource& src) GLenum unpackType, const TexImageSource& src)
{ {
TexImageTarget target; TexImageTarget target;
WebGLTexture* tex; WebGLTexture* tex;
if (!ValidateTexImageTarget(this, funcName, funcDims, rawTarget, &target, &tex)) if (!ValidateTexImageTarget(this, funcDims, rawTarget, &target, &tex))
return; return;
const webgl::PackingInfo pi = {unpackFormat, unpackType}; const webgl::PackingInfo pi = {unpackFormat, unpackType};
tex->TexImage(funcName, target, level, internalFormat, width, height, depth, border, tex->TexImage(target, level, internalFormat, width, height, depth, border,
pi, src); pi, src);
} }
void void
WebGLContext::TexSubImage(const char* funcName, uint8_t funcDims, GLenum rawTarget, WebGLContext::TexSubImage(uint8_t funcDims, GLenum rawTarget,
GLint level, GLint xOffset, GLint yOffset, GLint zOffset, GLint level, GLint xOffset, GLint yOffset, GLint zOffset,
GLsizei width, GLsizei height, GLsizei depth, GLsizei width, GLsizei height, GLsizei depth,
GLenum unpackFormat, GLenum unpackType, GLenum unpackFormat, GLenum unpackType,
@ -401,11 +393,11 @@ WebGLContext::TexSubImage(const char* funcName, uint8_t funcDims, GLenum rawTarg
{ {
TexImageTarget target; TexImageTarget target;
WebGLTexture* tex; WebGLTexture* tex;
if (!ValidateTexImageTarget(this, funcName, funcDims, rawTarget, &target, &tex)) if (!ValidateTexImageTarget(this, funcDims, rawTarget, &target, &tex))
return; return;
const webgl::PackingInfo pi = {unpackFormat, unpackType}; const webgl::PackingInfo pi = {unpackFormat, unpackType};
tex->TexSubImage(funcName, target, level, xOffset, yOffset, zOffset, width, height, tex->TexSubImage(target, level, xOffset, yOffset, zOffset, width, height,
depth, pi, src); depth, pi, src);
} }

Просмотреть файл

@ -89,7 +89,8 @@ WebGLContext::GenerateWarning(const char* fmt, va_list ap) const
} }
JSContext* cx = api.cx(); JSContext* cx = api.cx();
JS_ReportWarningASCII(cx, "WebGL warning: %s", buf); const auto funcName = FuncName();
JS_ReportWarningASCII(cx, "WebGL warning: %s: %s", funcName, buf);
if (!ShouldGenerateWarnings()) { if (!ShouldGenerateWarnings()) {
JS_ReportWarningASCII(cx, JS_ReportWarningASCII(cx,
"WebGL: No further warnings will be reported for" "WebGL: No further warnings will be reported for"
@ -134,7 +135,8 @@ WebGLContext::GeneratePerfWarning(const char* fmt, ...) const
//// ////
JS_ReportWarningASCII(cx, "WebGL perf warning: %s", buf); const auto funcName = FuncName();
JS_ReportWarningASCII(cx, "WebGL perf warning: %s: %s", funcName, buf);
mNumPerfWarnings++; mNumPerfWarnings++;
if (!ShouldGeneratePerfWarnings()) { if (!ShouldGeneratePerfWarnings()) {
@ -189,17 +191,6 @@ WebGLContext::ErrorInvalidEnumInfo(const char* info, GLenum enumValue) const
return ErrorInvalidEnum("%s: invalid enum value %s", info, name.BeginReading()); return ErrorInvalidEnum("%s: invalid enum value %s", info, name.BeginReading());
} }
void
WebGLContext::ErrorInvalidEnumInfo(const char* info, const char* funcName,
GLenum enumValue) const
{
nsCString name;
EnumName(enumValue, &name);
ErrorInvalidEnum("%s: %s: Invalid enum: 0x%04x (%s).", funcName, info,
enumValue, name.BeginReading());
}
void void
WebGLContext::ErrorInvalidOperation(const char* fmt, ...) const WebGLContext::ErrorInvalidOperation(const char* fmt, ...) const
{ {
@ -283,8 +274,8 @@ WebGLContext::ErrorName(GLenum error)
} }
// This version is fallible and will return nullptr if unrecognized. // This version is fallible and will return nullptr if unrecognized.
static const char* const char*
GetEnumName(GLenum val) GetEnumName(const GLenum val, const char* const defaultRet)
{ {
switch (val) { switch (val) {
#define XX(x) case LOCAL_GL_##x: return #x #define XX(x) case LOCAL_GL_##x: return #x
@ -609,13 +600,13 @@ GetEnumName(GLenum val)
#undef XX #undef XX
} }
return nullptr; return defaultRet;
} }
/*static*/ void /*static*/ void
WebGLContext::EnumName(GLenum val, nsCString* out_name) WebGLContext::EnumName(GLenum val, nsCString* out_name)
{ {
const char* name = GetEnumName(val); const char* name = GetEnumName(val, nullptr);
if (name) { if (name) {
*out_name = name; *out_name = name;
return; return;
@ -624,13 +615,24 @@ WebGLContext::EnumName(GLenum val, nsCString* out_name)
*out_name = nsPrintfCString("<enum 0x%04x>", val); *out_name = nsPrintfCString("<enum 0x%04x>", val);
} }
std::string
EnumString(const GLenum val)
{
const char* name = GetEnumName(val, nullptr);
if (name) {
return name;
}
const nsPrintfCString hex("<enum 0x%04x>", val);
return hex.BeginReading();
}
void void
WebGLContext::ErrorInvalidEnumArg(const char* funcName, const char* argName, WebGLContext::ErrorInvalidEnumArg(const char* argName, GLenum val) const
GLenum val) const
{ {
nsCString enumName; nsCString enumName;
EnumName(val, &enumName); EnumName(val, &enumName);
ErrorInvalidEnum("%s: Bad `%s`: %s", funcName, argName, enumName.BeginReading()); ErrorInvalidEnum("Bad `%s`: %s", argName, enumName.BeginReading());
} }
bool bool

Просмотреть файл

@ -147,26 +147,6 @@ WebGLContext::ValidateBlendFuncEnumsCompatibility(GLenum sfactor,
return true; return true;
} }
bool
WebGLContext::ValidateComparisonEnum(GLenum target, const char* info)
{
switch (target) {
case LOCAL_GL_NEVER:
case LOCAL_GL_LESS:
case LOCAL_GL_LEQUAL:
case LOCAL_GL_GREATER:
case LOCAL_GL_GEQUAL:
case LOCAL_GL_EQUAL:
case LOCAL_GL_NOTEQUAL:
case LOCAL_GL_ALWAYS:
return true;
default:
ErrorInvalidEnumInfo(info, target);
return false;
}
}
bool bool
WebGLContext::ValidateStencilOpEnum(GLenum action, const char* info) WebGLContext::ValidateStencilOpEnum(GLenum action, const char* info)
{ {
@ -188,7 +168,7 @@ WebGLContext::ValidateStencilOpEnum(GLenum action, const char* info)
} }
bool bool
WebGLContext::ValidateFaceEnum(GLenum face, const char* info) WebGLContext::ValidateFaceEnum(const GLenum face)
{ {
switch (face) { switch (face) {
case LOCAL_GL_FRONT: case LOCAL_GL_FRONT:
@ -197,32 +177,13 @@ WebGLContext::ValidateFaceEnum(GLenum face, const char* info)
return true; return true;
default: default:
ErrorInvalidEnumInfo(info, face); ErrorInvalidEnumInfo("face", face);
return false; return false;
} }
} }
bool bool
WebGLContext::ValidateDrawModeEnum(GLenum mode, const char* info) WebGLContext::ValidateUniformLocation(WebGLUniformLocation* loc)
{
switch (mode) {
case LOCAL_GL_TRIANGLES:
case LOCAL_GL_TRIANGLE_STRIP:
case LOCAL_GL_TRIANGLE_FAN:
case LOCAL_GL_POINTS:
case LOCAL_GL_LINE_STRIP:
case LOCAL_GL_LINE_LOOP:
case LOCAL_GL_LINES:
return true;
default:
ErrorInvalidEnumInfo(info, mode);
return false;
}
}
bool
WebGLContext::ValidateUniformLocation(WebGLUniformLocation* loc, const char* funcName)
{ {
/* GLES 2.0.25, p38: /* GLES 2.0.25, p38:
* If the value of location is -1, the Uniform* commands will silently * If the value of location is -1, the Uniform* commands will silently
@ -232,27 +193,25 @@ WebGLContext::ValidateUniformLocation(WebGLUniformLocation* loc, const char* fun
if (!loc) if (!loc)
return false; return false;
if (!ValidateObjectAllowDeleted(funcName, *loc)) if (!ValidateObjectAllowDeleted("loc", *loc))
return false; return false;
if (!mCurrentProgram) { if (!mCurrentProgram) {
ErrorInvalidOperation("%s: No program is currently bound.", funcName); ErrorInvalidOperation("No program is currently bound.");
return false; return false;
} }
return loc->ValidateForProgram(mCurrentProgram, funcName); return loc->ValidateForProgram(mCurrentProgram);
} }
bool bool
WebGLContext::ValidateAttribArraySetter(const char* name, uint32_t setterElemSize, WebGLContext::ValidateAttribArraySetter(uint32_t setterElemSize, uint32_t arrayLength)
uint32_t arrayLength)
{ {
if (IsContextLost()) if (IsContextLost())
return false; return false;
if (arrayLength < setterElemSize) { if (arrayLength < setterElemSize) {
ErrorInvalidValue("%s: Array must have >= %d elements.", name, ErrorInvalidValue("Array must have >= %d elements.", setterElemSize);
setterElemSize);
return false; return false;
} }
@ -261,16 +220,15 @@ WebGLContext::ValidateAttribArraySetter(const char* name, uint32_t setterElemSiz
bool bool
WebGLContext::ValidateUniformSetter(WebGLUniformLocation* loc, WebGLContext::ValidateUniformSetter(WebGLUniformLocation* loc,
uint8_t setterElemSize, GLenum setterType, uint8_t setterElemSize, GLenum setterType)
const char* funcName)
{ {
if (IsContextLost()) if (IsContextLost())
return false; return false;
if (!ValidateUniformLocation(loc, funcName)) if (!ValidateUniformLocation(loc))
return false; return false;
if (!loc->ValidateSizeAndType(setterElemSize, setterType, funcName)) if (!loc->ValidateSizeAndType(setterElemSize, setterType))
return false; return false;
return true; return true;
@ -281,19 +239,18 @@ WebGLContext::ValidateUniformArraySetter(WebGLUniformLocation* loc,
uint8_t setterElemSize, uint8_t setterElemSize,
GLenum setterType, GLenum setterType,
uint32_t setterArraySize, uint32_t setterArraySize,
const char* funcName,
uint32_t* const out_numElementsToUpload) uint32_t* const out_numElementsToUpload)
{ {
if (IsContextLost()) if (IsContextLost())
return false; return false;
if (!ValidateUniformLocation(loc, funcName)) if (!ValidateUniformLocation(loc))
return false; return false;
if (!loc->ValidateSizeAndType(setterElemSize, setterType, funcName)) if (!loc->ValidateSizeAndType(setterElemSize, setterType))
return false; return false;
if (!loc->ValidateArrayLength(setterElemSize, setterArraySize, funcName)) if (!loc->ValidateArrayLength(setterElemSize, setterArraySize))
return false; return false;
const auto& elemCount = loc->mInfo->mActiveInfo->mElemCount; const auto& elemCount = loc->mInfo->mActiveInfo->mElemCount;
@ -312,7 +269,6 @@ WebGLContext::ValidateUniformMatrixArraySetter(WebGLUniformLocation* loc,
GLenum setterType, GLenum setterType,
uint32_t setterArraySize, uint32_t setterArraySize,
bool setterTranspose, bool setterTranspose,
const char* funcName,
uint32_t* const out_numElementsToUpload) uint32_t* const out_numElementsToUpload)
{ {
const uint8_t setterElemSize = setterCols * setterRows; const uint8_t setterElemSize = setterCols * setterRows;
@ -320,17 +276,17 @@ WebGLContext::ValidateUniformMatrixArraySetter(WebGLUniformLocation* loc,
if (IsContextLost()) if (IsContextLost())
return false; return false;
if (!ValidateUniformLocation(loc, funcName)) if (!ValidateUniformLocation(loc))
return false; return false;
if (!loc->ValidateSizeAndType(setterElemSize, setterType, funcName)) if (!loc->ValidateSizeAndType(setterElemSize, setterType))
return false; return false;
if (!loc->ValidateArrayLength(setterElemSize, setterArraySize, funcName)) if (!loc->ValidateArrayLength(setterElemSize, setterArraySize))
return false; return false;
if (setterTranspose && !IsWebGL2()) { if (setterTranspose && !IsWebGL2()) {
ErrorInvalidValue("%s: `transpose` must be false.", funcName); ErrorInvalidValue("`transpose` must be false.");
return false; return false;
} }
@ -343,28 +299,6 @@ WebGLContext::ValidateUniformMatrixArraySetter(WebGLUniformLocation* loc,
return true; return true;
} }
bool
WebGLContext::ValidateAttribIndex(GLuint index, const char* info)
{
bool valid = (index < MaxVertexAttribs());
if (!valid) {
if (index == GLuint(-1)) {
ErrorInvalidValue("%s: -1 is not a valid `index`. This value"
" probably comes from a getAttribLocation()"
" call, where this return value -1 means"
" that the passed name didn't correspond to"
" an active attribute in the specified"
" program.", info);
} else {
ErrorInvalidValue("%s: `index` must be less than"
" MAX_VERTEX_ATTRIBS.", info);
}
}
return valid;
}
bool bool
WebGLContext::InitAndValidateGL(FailureReason* const out_failReason) WebGLContext::InitAndValidateGL(FailureReason* const out_failReason)
{ {
@ -755,8 +689,7 @@ WebGLContext::InitAndValidateGL(FailureReason* const out_failReason)
} }
bool bool
WebGLContext::ValidateFramebufferTarget(GLenum target, WebGLContext::ValidateFramebufferTarget(GLenum target)
const char* const info)
{ {
bool isValid = true; bool isValid = true;
switch (target) { switch (target) {
@ -777,7 +710,7 @@ WebGLContext::ValidateFramebufferTarget(GLenum target,
return true; return true;
} }
ErrorInvalidEnumArg(info, "target", target); ErrorInvalidEnumArg("target", target);
return false; return false;
} }

Просмотреть файл

@ -15,10 +15,11 @@ namespace mozilla {
void void
WebGLContext::BindVertexArray(WebGLVertexArray* array) WebGLContext::BindVertexArray(WebGLVertexArray* array)
{ {
const FuncScope funcScope(*this, "bindVertexArray");
if (IsContextLost()) if (IsContextLost())
return; return;
if (array && !ValidateObject("bindVertexArrayObject", *array)) if (array && !ValidateObject("array", *array))
return; return;
if (mBoundVertexArray) { if (mBoundVertexArray) {
@ -40,6 +41,7 @@ WebGLContext::BindVertexArray(WebGLVertexArray* array)
already_AddRefed<WebGLVertexArray> already_AddRefed<WebGLVertexArray>
WebGLContext::CreateVertexArray() WebGLContext::CreateVertexArray()
{ {
const FuncScope funcScope(*this, "createVertexArray");
if (IsContextLost()) if (IsContextLost())
return nullptr; return nullptr;
@ -59,7 +61,8 @@ WebGLContext::CreateVertexArrayImpl()
void void
WebGLContext::DeleteVertexArray(WebGLVertexArray* array) WebGLContext::DeleteVertexArray(WebGLVertexArray* array)
{ {
if (!ValidateDeleteObject("deleteVertexArray", array)) const FuncScope funcScope(*this, "deleteVertexArray");
if (!ValidateDeleteObject(array))
return; return;
if (mBoundVertexArray == array) if (mBoundVertexArray == array)
@ -68,13 +71,4 @@ WebGLContext::DeleteVertexArray(WebGLVertexArray* array)
array->RequestDelete(); array->RequestDelete();
} }
bool
WebGLContext::IsVertexArray(const WebGLVertexArray* array)
{
if (!ValidateIsObject("isVertexArray", array))
return false;
return array->IsVertexArray();
}
} // namespace mozilla } // namespace mozilla

Просмотреть файл

@ -20,6 +20,28 @@
namespace mozilla { namespace mozilla {
static bool
ValidateAttribIndex(WebGLContext& webgl, GLuint index)
{
bool valid = (index < webgl.MaxVertexAttribs());
if (!valid) {
if (index == GLuint(-1)) {
webgl.ErrorInvalidValue("-1 is not a valid `index`. This value"
" probably comes from a getAttribLocation()"
" call, where this return value -1 means"
" that the passed name didn't correspond to"
" an active attribute in the specified"
" program.");
} else {
webgl.ErrorInvalidValue("`index` must be less than"
" MAX_VERTEX_ATTRIBS.");
}
}
return valid;
}
JSObject* JSObject*
WebGLContext::GetVertexAttribFloat32Array(JSContext* cx, GLuint index) WebGLContext::GetVertexAttribFloat32Array(JSContext* cx, GLuint index)
{ {
@ -59,17 +81,13 @@ WebGLContext::GetVertexAttribUint32Array(JSContext* cx, GLuint index)
//////////////////////////////////////// ////////////////////////////////////////
void void
WebGLContext::VertexAttrib4f(GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w, WebGLContext::VertexAttrib4f(GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
const char* funcName)
{ {
if (!funcName) { const FuncScope funcScope(*this, "vertexAttrib4f");
funcName = "vertexAttrib4f";
}
if (IsContextLost()) if (IsContextLost())
return; return;
if (!ValidateAttribIndex(index, funcName)) if (!ValidateAttribIndex(*this, index))
return; return;
//// ////
@ -90,17 +108,13 @@ WebGLContext::VertexAttrib4f(GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfl
} }
void void
WebGL2Context::VertexAttribI4i(GLuint index, GLint x, GLint y, GLint z, GLint w, WebGL2Context::VertexAttribI4i(GLuint index, GLint x, GLint y, GLint z, GLint w)
const char* funcName)
{ {
if (!funcName) { const FuncScope funcScope(*this, "vertexAttribI4i");
funcName = "vertexAttribI4i";
}
if (IsContextLost()) if (IsContextLost())
return; return;
if (!ValidateAttribIndex(index, funcName)) if (!ValidateAttribIndex(*this, index))
return; return;
//// ////
@ -121,17 +135,13 @@ WebGL2Context::VertexAttribI4i(GLuint index, GLint x, GLint y, GLint z, GLint w,
} }
void void
WebGL2Context::VertexAttribI4ui(GLuint index, GLuint x, GLuint y, GLuint z, GLuint w, WebGL2Context::VertexAttribI4ui(GLuint index, GLuint x, GLuint y, GLuint z, GLuint w)
const char* funcName)
{ {
if (!funcName) { const FuncScope funcScope(*this, "vertexAttribI4ui");
funcName = "vertexAttribI4ui";
}
if (IsContextLost()) if (IsContextLost())
return; return;
if (!ValidateAttribIndex(index, funcName)) if (!ValidateAttribIndex(*this, index))
return; return;
//// ////
@ -156,10 +166,11 @@ WebGL2Context::VertexAttribI4ui(GLuint index, GLuint x, GLuint y, GLuint z, GLui
void void
WebGLContext::EnableVertexAttribArray(GLuint index) WebGLContext::EnableVertexAttribArray(GLuint index)
{ {
const FuncScope funcScope(*this, "enableVertexAttribArray");
if (IsContextLost()) if (IsContextLost())
return; return;
if (!ValidateAttribIndex(index, "enableVertexAttribArray")) if (!ValidateAttribIndex(*this, index))
return; return;
gl->fEnableVertexAttribArray(index); gl->fEnableVertexAttribArray(index);
@ -172,10 +183,11 @@ WebGLContext::EnableVertexAttribArray(GLuint index)
void void
WebGLContext::DisableVertexAttribArray(GLuint index) WebGLContext::DisableVertexAttribArray(GLuint index)
{ {
const FuncScope funcScope(*this, "disableVertexAttribArray");
if (IsContextLost()) if (IsContextLost())
return; return;
if (!ValidateAttribIndex(index, "disableVertexAttribArray")) if (!ValidateAttribIndex(*this, index))
return; return;
if (index || !gl->IsCompatibilityProfile()) { if (index || !gl->IsCompatibilityProfile()) {
@ -191,11 +203,11 @@ JS::Value
WebGLContext::GetVertexAttrib(JSContext* cx, GLuint index, GLenum pname, WebGLContext::GetVertexAttrib(JSContext* cx, GLuint index, GLenum pname,
ErrorResult& rv) ErrorResult& rv)
{ {
const char funcName[] = "getVertexAttrib"; const FuncScope funcScope(*this, "getVertexAttrib");
if (IsContextLost()) if (IsContextLost())
return JS::NullValue(); return JS::NullValue();
if (!ValidateAttribIndex(index, funcName)) if (!ValidateAttribIndex(*this, index))
return JS::NullValue(); return JS::NullValue();
MOZ_ASSERT(mBoundVertexArray); MOZ_ASSERT(mBoundVertexArray);
@ -261,21 +273,22 @@ WebGLContext::GetVertexAttrib(JSContext* cx, GLuint index, GLenum pname,
break; break;
} }
ErrorInvalidEnumInfo("getVertexAttrib: parameter", pname); ErrorInvalidEnumInfo("pname", pname);
return JS::NullValue(); return JS::NullValue();
} }
WebGLsizeiptr WebGLsizeiptr
WebGLContext::GetVertexAttribOffset(GLuint index, GLenum pname) WebGLContext::GetVertexAttribOffset(GLuint index, GLenum pname)
{ {
const FuncScope funcScope(*this, "getVertexAttribOffset");
if (IsContextLost()) if (IsContextLost())
return 0; return 0;
if (!ValidateAttribIndex(index, "getVertexAttribOffset")) if (!ValidateAttribIndex(*this, index))
return 0; return 0;
if (pname != LOCAL_GL_VERTEX_ATTRIB_ARRAY_POINTER) { if (pname != LOCAL_GL_VERTEX_ATTRIB_ARRAY_POINTER) {
ErrorInvalidEnum("getVertexAttribOffset: bad parameter"); ErrorInvalidEnum("`pname` must be VERTEX_ATTRIB_ARRAY_POINTER.");
return 0; return 0;
} }
@ -286,31 +299,31 @@ WebGLContext::GetVertexAttribOffset(GLuint index, GLenum pname)
//////////////////////////////////////// ////////////////////////////////////////
void void
WebGLContext::VertexAttribAnyPointer(const char* funcName, bool isFuncInt, GLuint index, WebGLContext::VertexAttribAnyPointer(bool isFuncInt, GLuint index,
GLint size, GLenum type, bool normalized, GLint size, GLenum type, bool normalized,
GLsizei stride, WebGLintptr byteOffset) GLsizei stride, WebGLintptr byteOffset)
{ {
if (IsContextLost()) if (IsContextLost())
return; return;
if (!ValidateAttribIndex(index, funcName)) if (!ValidateAttribIndex(*this, index))
return; return;
//// ////
if (size < 1 || size > 4) { if (size < 1 || size > 4) {
ErrorInvalidValue("%s: invalid element size", funcName); ErrorInvalidValue("Invalid element size.");
return; return;
} }
// see WebGL spec section 6.6 "Vertex Attribute Data Stride" // see WebGL spec section 6.6 "Vertex Attribute Data Stride"
if (stride < 0 || stride > 255) { if (stride < 0 || stride > 255) {
ErrorInvalidValue("%s: negative or too large stride", funcName); ErrorInvalidValue("Negative or too large stride.");
return; return;
} }
if (byteOffset < 0) { if (byteOffset < 0) {
ErrorInvalidValue("%s: negative offset", funcName); ErrorInvalidValue("Negative offset.");
return; return;
} }
@ -367,7 +380,7 @@ WebGLContext::VertexAttribAnyPointer(const char* funcName, bool isFuncInt, GLuin
break; break;
} }
if (size != 4) { if (size != 4) {
ErrorInvalidOperation("%s: size must be 4 for this type.", funcName); ErrorInvalidOperation("Size must be 4 for this type.");
return; return;
} }
typeAlignment = 4; typeAlignment = 4;
@ -378,7 +391,7 @@ WebGLContext::VertexAttribAnyPointer(const char* funcName, bool isFuncInt, GLuin
break; break;
} }
if (!isTypeValid) { if (!isTypeValid) {
ErrorInvalidEnumArg(funcName, "type", type); ErrorInvalidEnumInfo("type", type);
return; return;
} }
@ -391,9 +404,8 @@ WebGLContext::VertexAttribAnyPointer(const char* funcName, bool isFuncInt, GLuin
if (stride & typeAlignmentMask || if (stride & typeAlignmentMask ||
byteOffset & typeAlignmentMask) byteOffset & typeAlignmentMask)
{ {
ErrorInvalidOperation("%s: `stride` and `byteOffset` must satisfy the alignment" ErrorInvalidOperation("`stride` and `byteOffset` must satisfy the alignment"
" requirement of `type`.", " requirement of `type`.");
funcName);
return; return;
} }
@ -401,8 +413,7 @@ WebGLContext::VertexAttribAnyPointer(const char* funcName, bool isFuncInt, GLuin
const auto& buffer = mBoundArrayBuffer; const auto& buffer = mBoundArrayBuffer;
if (!buffer && byteOffset) { if (!buffer && byteOffset) {
ErrorInvalidOperation("%s: If ARRAY_BUFFER is null, byteOffset must be zero.", ErrorInvalidOperation("If ARRAY_BUFFER is null, byteOffset must be zero.");
funcName);
return; return;
} }
@ -426,10 +437,11 @@ WebGLContext::VertexAttribAnyPointer(const char* funcName, bool isFuncInt, GLuin
void void
WebGLContext::VertexAttribDivisor(GLuint index, GLuint divisor) WebGLContext::VertexAttribDivisor(GLuint index, GLuint divisor)
{ {
const FuncScope funcScope(*this, "vertexAttribDivisor");
if (IsContextLost()) if (IsContextLost())
return; return;
if (!ValidateAttribIndex(index, "vertexAttribDivisor")) if (!ValidateAttribIndex(*this, index))
return; return;
MOZ_ASSERT(mBoundVertexArray); MOZ_ASSERT(mBoundVertexArray);

Просмотреть файл

@ -28,17 +28,13 @@ WebGLExtensionDebugShaders::GetTranslatedShaderSource(const WebGLShader& shader,
nsAString& retval) const nsAString& retval) const
{ {
retval.SetIsVoid(true); retval.SetIsVoid(true);
if (mIsLost)
if (mIsLost) {
mContext->ErrorInvalidOperation("%s: Extension is lost.",
"getTranslatedShaderSource");
return;
}
if (mContext->IsContextLost())
return; return;
if (!mContext->ValidateObject("getShaderTranslatedSource: shader", shader)) const WebGLContext::FuncScope funcScope(*mContext, "getShaderTranslatedSource");
MOZ_ASSERT(!mContext->IsContextLost());
if (!mContext->ValidateObject("shader", shader))
return; return;
shader.GetShaderTranslatedSource(&retval); shader.GetShaderTranslatedSource(&retval);

Просмотреть файл

@ -29,76 +29,83 @@ WebGLExtensionDisjointTimerQuery::~WebGLExtensionDisjointTimerQuery()
already_AddRefed<WebGLQuery> already_AddRefed<WebGLQuery>
WebGLExtensionDisjointTimerQuery::CreateQueryEXT() const WebGLExtensionDisjointTimerQuery::CreateQueryEXT() const
{ {
const char funcName[] = "createQueryEXT";
if (mIsLost) if (mIsLost)
return nullptr; return nullptr;
const WebGLContext::FuncScope funcScope(*mContext, "createQueryEXT");
MOZ_ASSERT(!mContext->IsContextLost());
return mContext->CreateQuery(funcName); return mContext->CreateQuery();
} }
void void
WebGLExtensionDisjointTimerQuery::DeleteQueryEXT(WebGLQuery* query) const WebGLExtensionDisjointTimerQuery::DeleteQueryEXT(WebGLQuery* query) const
{ {
const char funcName[] = "deleteQueryEXT";
if (mIsLost) if (mIsLost)
return; return;
const WebGLContext::FuncScope funcScope(*mContext, "deleteQueryEXT");
MOZ_ASSERT(!mContext->IsContextLost());
mContext->DeleteQuery(query, funcName); mContext->DeleteQuery(query);
} }
bool bool
WebGLExtensionDisjointTimerQuery::IsQueryEXT(const WebGLQuery* query) const WebGLExtensionDisjointTimerQuery::IsQueryEXT(const WebGLQuery* query) const
{ {
const char funcName[] = "isQueryEXT";
if (mIsLost) if (mIsLost)
return false; return false;
const WebGLContext::FuncScope funcScope(*mContext, "isQueryEXT");
MOZ_ASSERT(!mContext->IsContextLost());
return mContext->IsQuery(query, funcName); return mContext->IsQuery(query);
} }
void void
WebGLExtensionDisjointTimerQuery::BeginQueryEXT(GLenum target, WebGLQuery& query) const WebGLExtensionDisjointTimerQuery::BeginQueryEXT(GLenum target, WebGLQuery& query) const
{ {
const char funcName[] = "beginQueryEXT";
if (mIsLost) if (mIsLost)
return; return;
const WebGLContext::FuncScope funcScope(*mContext, "beginQueryEXT");
MOZ_ASSERT(!mContext->IsContextLost());
mContext->BeginQuery(target, query, funcName); mContext->BeginQuery(target, query);
} }
void void
WebGLExtensionDisjointTimerQuery::EndQueryEXT(GLenum target) const WebGLExtensionDisjointTimerQuery::EndQueryEXT(GLenum target) const
{ {
const char funcName[] = "endQueryEXT";
if (mIsLost) if (mIsLost)
return; return;
const WebGLContext::FuncScope funcScope(*mContext, "endQueryEXT");
MOZ_ASSERT(!mContext->IsContextLost());
mContext->EndQuery(target, funcName); mContext->EndQuery(target);
} }
void void
WebGLExtensionDisjointTimerQuery::QueryCounterEXT(WebGLQuery& query, GLenum target) const WebGLExtensionDisjointTimerQuery::QueryCounterEXT(WebGLQuery& query, GLenum target) const
{ {
const char funcName[] = "queryCounterEXT";
if (mIsLost) if (mIsLost)
return; return;
const WebGLContext::FuncScope funcScope(*mContext, "queryCounterEXT");
MOZ_ASSERT(!mContext->IsContextLost());
if (!mContext->ValidateObject(funcName, query)) if (!mContext->ValidateObject("query", query))
return; return;
query.QueryCounter(funcName, target); query.QueryCounter(target);
} }
void void
WebGLExtensionDisjointTimerQuery::GetQueryEXT(JSContext* cx, GLenum target, GLenum pname, WebGLExtensionDisjointTimerQuery::GetQueryEXT(JSContext* cx, GLenum target, GLenum pname,
JS::MutableHandleValue retval) const JS::MutableHandleValue retval) const
{ {
const char funcName[] = "getQueryEXT";
retval.setNull(); retval.setNull();
if (mIsLost) if (mIsLost)
return; return;
const WebGLContext::FuncScope funcScope(*mContext, "getQueryEXT");
MOZ_ASSERT(!mContext->IsContextLost());
mContext->GetQuery(cx, target, pname, retval, funcName); mContext->GetQuery(cx, target, pname, retval);
} }
void void
@ -106,12 +113,13 @@ WebGLExtensionDisjointTimerQuery::GetQueryObjectEXT(JSContext* cx,
const WebGLQuery& query, GLenum pname, const WebGLQuery& query, GLenum pname,
JS::MutableHandleValue retval) const JS::MutableHandleValue retval) const
{ {
const char funcName[] = "getQueryObjectEXT";
retval.setNull(); retval.setNull();
if (mIsLost) if (mIsLost)
return; return;
const WebGLContext::FuncScope funcScope(*mContext, "getQueryObjectEXT");
MOZ_ASSERT(!mContext->IsContextLost());
mContext->GetQueryParameter(cx, query, pname, retval, funcName); mContext->GetQueryParameter(cx, query, pname, retval);
} }
bool bool

Просмотреть файл

@ -26,6 +26,11 @@ WebGLExtensionMOZDebug::GetParameter(JSContext* cx, GLenum pname,
JS::MutableHandle<JS::Value> retval, JS::MutableHandle<JS::Value> retval,
ErrorResult& er) const ErrorResult& er) const
{ {
if (mIsLost)
return;
const WebGLContext::FuncScope funcScope(*mContext, "MOZ_debug.getParameter");
MOZ_ASSERT(!mContext->IsContextLost());
const auto& gl = mContext->gl; const auto& gl = mContext->gl;
switch (pname) { switch (pname) {
@ -72,7 +77,7 @@ WebGLExtensionMOZDebug::GetParameter(JSContext* cx, GLenum pname,
return; return;
default: default:
mContext->ErrorInvalidEnumArg("MOZ_debug.getParameter", "pname", pname); mContext->ErrorInvalidEnumInfo("pname", pname);
retval.set(JS::NullValue()); retval.set(JS::NullValue());
return; return;
} }

Просмотреть файл

@ -47,8 +47,7 @@ WebGLFBAttachPoint::~WebGLFBAttachPoint()
void void
WebGLFBAttachPoint::Unlink() WebGLFBAttachPoint::Unlink()
{ {
const char funcName[] = "WebGLFramebuffer::GC"; Clear();
Clear(funcName);
} }
bool bool
@ -115,7 +114,7 @@ WebGLFBAttachPoint::IsReadableFloat() const
} }
void void
WebGLFBAttachPoint::Clear(const char* funcName) WebGLFBAttachPoint::Clear()
{ {
if (mRenderbufferPtr) { if (mRenderbufferPtr) {
MOZ_ASSERT(!mTexturePtr); MOZ_ASSERT(!mTexturePtr);
@ -127,14 +126,14 @@ WebGLFBAttachPoint::Clear(const char* funcName)
mTexturePtr = nullptr; mTexturePtr = nullptr;
mRenderbufferPtr = nullptr; mRenderbufferPtr = nullptr;
OnBackingStoreRespecified(funcName); OnBackingStoreRespecified();
} }
void void
WebGLFBAttachPoint::SetTexImage(const char* funcName, WebGLTexture* tex, WebGLFBAttachPoint::SetTexImage(WebGLTexture* tex,
TexImageTarget target, GLint level, GLint layer) TexImageTarget target, GLint level, GLint layer)
{ {
Clear(funcName); Clear();
mTexturePtr = tex; mTexturePtr = tex;
mTexImageTarget = target; mTexImageTarget = target;
@ -147,9 +146,9 @@ WebGLFBAttachPoint::SetTexImage(const char* funcName, WebGLTexture* tex,
} }
void void
WebGLFBAttachPoint::SetRenderbuffer(const char* funcName, WebGLRenderbuffer* rb) WebGLFBAttachPoint::SetRenderbuffer(WebGLRenderbuffer* rb)
{ {
Clear(funcName); Clear();
mRenderbufferPtr = rb; mRenderbufferPtr = rb;
@ -227,9 +226,9 @@ WebGLFBAttachPoint::Size(uint32_t* const out_width, uint32_t* const out_height)
} }
void void
WebGLFBAttachPoint::OnBackingStoreRespecified(const char* funcName) const WebGLFBAttachPoint::OnBackingStoreRespecified() const
{ {
mFB->InvalidateFramebufferStatus(funcName); mFB->InvalidateFramebufferStatus();
} }
void void
@ -402,7 +401,7 @@ WebGLFBAttachPoint::Resolve(gl::GLContext* gl) const
} }
JS::Value JS::Value
WebGLFBAttachPoint::GetParameter(const char* funcName, WebGLContext* webgl, JSContext* cx, WebGLFBAttachPoint::GetParameter(WebGLContext* webgl, JSContext* cx,
GLenum target, GLenum attachment, GLenum pname, GLenum target, GLenum attachment, GLenum pname,
ErrorResult* const out_error) const ErrorResult* const out_error) const
{ {
@ -435,10 +434,10 @@ WebGLFBAttachPoint::GetParameter(const char* funcName, WebGLContext* webgl, JSCo
nsCString attachmentName; nsCString attachmentName;
WebGLContext::EnumName(attachment, &attachmentName); WebGLContext::EnumName(attachment, &attachmentName);
if (webgl->IsWebGL2()) { if (webgl->IsWebGL2()) {
webgl->ErrorInvalidOperation("%s: No attachment at %s.", funcName, webgl->ErrorInvalidOperation("No attachment at %s.",
attachmentName.BeginReading()); attachmentName.BeginReading());
} else { } else {
webgl->ErrorInvalidEnum("%s: No attachment at %s.", funcName, webgl->ErrorInvalidEnum("No attachment at %s.",
attachmentName.BeginReading()); attachmentName.BeginReading());
} }
return JS::NullValue(); return JS::NullValue();
@ -506,7 +505,7 @@ WebGLFBAttachPoint::GetParameter(const char* funcName, WebGLContext* webgl, JSCo
} }
if (!isPNameValid) { if (!isPNameValid) {
webgl->ErrorInvalidEnum("%s: Invalid pname: 0x%04x", funcName, pname); webgl->ErrorInvalidEnum("Invalid pname: 0x%04x", pname);
return JS::NullValue(); return JS::NullValue();
} }
@ -643,16 +642,14 @@ WebGLFramebuffer::WebGLFramebuffer(WebGLContext* webgl, GLuint fbo)
void void
WebGLFramebuffer::Delete() WebGLFramebuffer::Delete()
{ {
const char funcName[] = "WebGLFramebuffer::Delete"; InvalidateFramebufferStatus();
InvalidateFramebufferStatus(funcName); mDepthAttachment.Clear();
mStencilAttachment.Clear();
mDepthAttachment.Clear(funcName); mDepthStencilAttachment.Clear();
mStencilAttachment.Clear(funcName);
mDepthStencilAttachment.Clear(funcName);
for (auto& cur : mColorAttachments) { for (auto& cur : mColorAttachments) {
cur.Clear(funcName); cur.Clear();
} }
mContext->gl->fDeleteFramebuffers(1, &mGLName); mContext->gl->fDeleteFramebuffers(1, &mGLName);
@ -712,11 +709,11 @@ WebGLFramebuffer::GetAttachPoint(GLenum attachPoint)
} }
void void
WebGLFramebuffer::DetachTexture(const char* funcName, const WebGLTexture* tex) WebGLFramebuffer::DetachTexture(const WebGLTexture* tex)
{ {
const auto fnDetach = [&](WebGLFBAttachPoint& attach) { const auto fnDetach = [&](WebGLFBAttachPoint& attach) {
if (attach.Texture() == tex) { if (attach.Texture() == tex) {
attach.Clear(funcName); attach.Clear();
} }
}; };
@ -724,11 +721,11 @@ WebGLFramebuffer::DetachTexture(const char* funcName, const WebGLTexture* tex)
} }
void void
WebGLFramebuffer::DetachRenderbuffer(const char* funcName, const WebGLRenderbuffer* rb) WebGLFramebuffer::DetachRenderbuffer(const WebGLRenderbuffer* rb)
{ {
const auto fnDetach = [&](WebGLFBAttachPoint& attach) { const auto fnDetach = [&](WebGLFBAttachPoint& attach) {
if (attach.Renderbuffer() == rb) { if (attach.Renderbuffer() == rb) {
attach.Clear(funcName); attach.Clear();
} }
}; };
@ -889,23 +886,21 @@ WebGLFramebuffer::PrecheckFramebufferStatus(nsCString* const out_info) const
// Validation // Validation
bool bool
WebGLFramebuffer::ValidateAndInitAttachments(const char* funcName) const WebGLFramebuffer::ValidateAndInitAttachments() const
{ {
MOZ_ASSERT(mContext->mBoundDrawFramebuffer == this || MOZ_ASSERT(mContext->mBoundDrawFramebuffer == this ||
mContext->mBoundReadFramebuffer == this); mContext->mBoundReadFramebuffer == this);
const auto fbStatus = CheckFramebufferStatus(funcName); const auto fbStatus = CheckFramebufferStatus();
if (fbStatus == LOCAL_GL_FRAMEBUFFER_COMPLETE) if (fbStatus == LOCAL_GL_FRAMEBUFFER_COMPLETE)
return true; return true;
mContext->ErrorInvalidFramebufferOperation("%s: Framebuffer must be" mContext->ErrorInvalidFramebufferOperation("Framebuffer must be complete.");
" complete.",
funcName);
return false; return false;
} }
bool bool
WebGLFramebuffer::ValidateClearBufferType(const char* funcName, GLenum buffer, WebGLFramebuffer::ValidateClearBufferType(GLenum buffer,
uint32_t drawBuffer, GLenum funcType) const uint32_t drawBuffer, GLenum funcType) const
{ {
if (buffer != LOCAL_GL_COLOR) if (buffer != LOCAL_GL_COLOR)
@ -932,9 +927,9 @@ WebGLFramebuffer::ValidateClearBufferType(const char* funcName, GLenum buffer,
} }
if (attachType != funcType) { if (attachType != funcType) {
mContext->ErrorInvalidOperation("%s: This attachment is of type 0x%04x, but" mContext->ErrorInvalidOperation("This attachment is of type 0x%04x, but"
" this function is of type 0x%04x.", " this function is of type 0x%04x.",
funcName, attachType, funcType); attachType, funcType);
return false; return false;
} }
@ -942,25 +937,22 @@ WebGLFramebuffer::ValidateClearBufferType(const char* funcName, GLenum buffer,
} }
bool bool
WebGLFramebuffer::ValidateForColorRead(const char* funcName, WebGLFramebuffer::ValidateForColorRead(const webgl::FormatUsageInfo** const out_format,
const webgl::FormatUsageInfo** const out_format,
uint32_t* const out_width, uint32_t* const out_width,
uint32_t* const out_height) const uint32_t* const out_height) const
{ {
if (!mColorReadBuffer) { if (!mColorReadBuffer) {
mContext->ErrorInvalidOperation("%s: READ_BUFFER must not be NONE.", funcName); mContext->ErrorInvalidOperation("READ_BUFFER must not be NONE.");
return false; return false;
} }
if (!mColorReadBuffer->IsDefined()) { if (!mColorReadBuffer->IsDefined()) {
mContext->ErrorInvalidOperation("%s: The READ_BUFFER attachment is not defined.", mContext->ErrorInvalidOperation("The READ_BUFFER attachment is not defined.");
funcName);
return false; return false;
} }
if (mColorReadBuffer->Samples()) { if (mColorReadBuffer->Samples()) {
mContext->ErrorInvalidOperation("%s: The READ_BUFFER attachment is multisampled.", mContext->ErrorInvalidOperation("The READ_BUFFER attachment is multisampled.");
funcName);
return false; return false;
} }
@ -1003,7 +995,7 @@ WebGLFramebuffer::ResolveAttachments() const
} }
bool bool
WebGLFramebuffer::ResolveAttachmentData(const char* funcName) const WebGLFramebuffer::ResolveAttachmentData() const
{ {
////// //////
// Check if we need to initialize anything // Check if we need to initialize anything
@ -1056,7 +1048,7 @@ WebGLFramebuffer::ResolveAttachmentData(const char* funcName) const
for (const auto& attach : tex3DAttachmentsToInit) { for (const auto& attach : tex3DAttachmentsToInit) {
const auto& tex = attach->Texture(); const auto& tex = attach->Texture();
if (!tex->InitializeImageData(funcName, attach->ImageTarget(), if (!tex->InitializeImageData(attach->ImageTarget(),
attach->MipLevel())) attach->MipLevel()))
{ {
return false; return false;
@ -1157,14 +1149,14 @@ WebGLFramebuffer::ResolvedData::ResolvedData(const WebGLFramebuffer& parent)
} }
void void
WebGLFramebuffer::InvalidateFramebufferStatus(const char* funcName) WebGLFramebuffer::InvalidateFramebufferStatus()
{ {
if (mResolvedCompleteData) { if (mResolvedCompleteData) {
mNumFBStatusInvals++; mNumFBStatusInvals++;
if (mNumFBStatusInvals > mContext->mMaxAcceptableFBStatusInvals) { if (mNumFBStatusInvals > mContext->mMaxAcceptableFBStatusInvals) {
mContext->GeneratePerfWarning("%s: FB was invalidated after being complete %u" mContext->GeneratePerfWarning("FB was invalidated after being complete %u"
" times.", " times.",
funcName, uint32_t(mNumFBStatusInvals)); uint32_t(mNumFBStatusInvals));
} }
} }
@ -1183,7 +1175,7 @@ WebGLFramebuffer::RefreshResolvedData()
// Entrypoints // Entrypoints
FBStatus FBStatus
WebGLFramebuffer::CheckFramebufferStatus(const char* const funcName) const WebGLFramebuffer::CheckFramebufferStatus() const
{ {
if (IsResolvedComplete()) if (IsResolvedComplete())
return LOCAL_GL_FRAMEBUFFER_COMPLETE; return LOCAL_GL_FRAMEBUFFER_COMPLETE;
@ -1219,7 +1211,7 @@ WebGLFramebuffer::CheckFramebufferStatus(const char* const funcName) const
break; break;
} }
if (!ResolveAttachmentData(funcName)) { if (!ResolveAttachmentData()) {
ret = LOCAL_GL_FRAMEBUFFER_UNSUPPORTED; ret = LOCAL_GL_FRAMEBUFFER_UNSUPPORTED;
statusInfo.AssignLiteral("Failed to lazily-initialize attachment data."); statusInfo.AssignLiteral("Failed to lazily-initialize attachment data.");
break; break;
@ -1230,8 +1222,8 @@ WebGLFramebuffer::CheckFramebufferStatus(const char* const funcName) const
} while (false); } while (false);
MOZ_ASSERT(ret != LOCAL_GL_FRAMEBUFFER_COMPLETE); MOZ_ASSERT(ret != LOCAL_GL_FRAMEBUFFER_COMPLETE);
mContext->GenerateWarning("%s: Framebuffer not complete. (status: 0x%04x) %s", mContext->GenerateWarning("Framebuffer not complete. (status: 0x%04x) %s",
funcName, ret.get(), statusInfo.BeginReading()); ret.get(), statusInfo.BeginReading());
return ret; return ret;
} }
@ -1281,12 +1273,12 @@ WebGLFramebuffer::RefreshReadBuffer() const
//// ////
void void
WebGLFramebuffer::DrawBuffers(const char* funcName, const dom::Sequence<GLenum>& buffers) WebGLFramebuffer::DrawBuffers(const dom::Sequence<GLenum>& buffers)
{ {
if (buffers.Length() > mContext->mGLMaxDrawBuffers) { if (buffers.Length() > mContext->mGLMaxDrawBuffers) {
// "An INVALID_VALUE error is generated if `n` is greater than MAX_DRAW_BUFFERS." // "An INVALID_VALUE error is generated if `n` is greater than MAX_DRAW_BUFFERS."
mContext->ErrorInvalidValue("%s: `buffers` must have a length <=" mContext->ErrorInvalidValue("`buffers` must have a length <="
" MAX_DRAW_BUFFERS.", funcName); " MAX_DRAW_BUFFERS.");
return; return;
} }
@ -1314,13 +1306,12 @@ WebGLFramebuffer::DrawBuffers(const char* funcName, const dom::Sequence<GLenum>&
if (cur != LOCAL_GL_BACK && if (cur != LOCAL_GL_BACK &&
!isColorEnum) !isColorEnum)
{ {
mContext->ErrorInvalidEnum("%s: Unexpected enum in buffers.", funcName); mContext->ErrorInvalidEnum("Unexpected enum in buffers.");
return; return;
} }
mContext->ErrorInvalidOperation("%s: `buffers[i]` must be NONE or" mContext->ErrorInvalidOperation("`buffers[i]` must be NONE or"
" COLOR_ATTACHMENTi.", " COLOR_ATTACHMENTi.");
funcName);
return; return;
} }
} }
@ -1333,16 +1324,16 @@ WebGLFramebuffer::DrawBuffers(const char* funcName, const dom::Sequence<GLenum>&
} }
void void
WebGLFramebuffer::ReadBuffer(const char* funcName, GLenum attachPoint) WebGLFramebuffer::ReadBuffer(GLenum attachPoint)
{ {
const auto& maybeAttach = GetColorAttachPoint(attachPoint); const auto& maybeAttach = GetColorAttachPoint(attachPoint);
if (!maybeAttach) { if (!maybeAttach) {
const char text[] = "%s: `mode` must be a COLOR_ATTACHMENTi, for 0 <= i <" const char text[] = "`mode` must be a COLOR_ATTACHMENTi, for 0 <= i <"
" MAX_DRAW_BUFFERS."; " MAX_DRAW_BUFFERS.";
if (attachPoint == LOCAL_GL_BACK) { if (attachPoint == LOCAL_GL_BACK) {
mContext->ErrorInvalidOperation(text, funcName); mContext->ErrorInvalidOperation(text);
} else { } else {
mContext->ErrorInvalidEnum(text, funcName); mContext->ErrorInvalidEnum(text);
} }
return; return;
} }
@ -1358,7 +1349,7 @@ WebGLFramebuffer::ReadBuffer(const char* funcName, GLenum attachPoint)
//// ////
void void
WebGLFramebuffer::FramebufferRenderbuffer(const char* funcName, GLenum attachEnum, WebGLFramebuffer::FramebufferRenderbuffer(GLenum attachEnum,
GLenum rbtarget, WebGLRenderbuffer* rb) GLenum rbtarget, WebGLRenderbuffer* rb)
{ {
MOZ_ASSERT(mContext->mBoundDrawFramebuffer == this || MOZ_ASSERT(mContext->mBoundDrawFramebuffer == this ||
@ -1367,26 +1358,26 @@ WebGLFramebuffer::FramebufferRenderbuffer(const char* funcName, GLenum attachEnu
// `attachment` // `attachment`
const auto maybeAttach = GetAttachPoint(attachEnum); const auto maybeAttach = GetAttachPoint(attachEnum);
if (!maybeAttach || !maybeAttach.value()) { if (!maybeAttach || !maybeAttach.value()) {
mContext->ErrorInvalidEnum("%s: Bad `attachment`: 0x%x.", funcName, attachEnum); mContext->ErrorInvalidEnum("Bad `attachment`: 0x%x.", attachEnum);
return; return;
} }
const auto& attach = maybeAttach.value(); const auto& attach = maybeAttach.value();
// `rbTarget` // `rbTarget`
if (rbtarget != LOCAL_GL_RENDERBUFFER) { if (rbtarget != LOCAL_GL_RENDERBUFFER) {
mContext->ErrorInvalidEnumInfo("framebufferRenderbuffer: rbtarget:", rbtarget); mContext->ErrorInvalidEnumInfo("rbtarget", rbtarget);
return; return;
} }
// `rb` // `rb`
if (rb) { if (rb) {
if (!mContext->ValidateObject("framebufferRenderbuffer: rb", *rb)) if (!mContext->ValidateObject("rb", *rb))
return; return;
if (!rb->mHasBeenBound) { if (!rb->mHasBeenBound) {
mContext->ErrorInvalidOperation("%s: bindRenderbuffer must be called before" mContext->ErrorInvalidOperation("bindRenderbuffer must be called before"
" attachment to %04x", " attachment to %04x",
funcName, attachEnum); attachEnum);
return; return;
} }
} }
@ -1394,17 +1385,17 @@ WebGLFramebuffer::FramebufferRenderbuffer(const char* funcName, GLenum attachEnu
// End of validation. // End of validation.
if (mContext->IsWebGL2() && attachEnum == LOCAL_GL_DEPTH_STENCIL_ATTACHMENT) { if (mContext->IsWebGL2() && attachEnum == LOCAL_GL_DEPTH_STENCIL_ATTACHMENT) {
mDepthAttachment.SetRenderbuffer(funcName, rb); mDepthAttachment.SetRenderbuffer(rb);
mStencilAttachment.SetRenderbuffer(funcName, rb); mStencilAttachment.SetRenderbuffer(rb);
} else { } else {
attach->SetRenderbuffer(funcName, rb); attach->SetRenderbuffer(rb);
} }
InvalidateFramebufferStatus(funcName); InvalidateFramebufferStatus();
} }
void void
WebGLFramebuffer::FramebufferTexture2D(const char* funcName, GLenum attachEnum, WebGLFramebuffer::FramebufferTexture2D(GLenum attachEnum,
GLenum texImageTarget, WebGLTexture* tex, GLenum texImageTarget, WebGLTexture* tex,
GLint level) GLint level)
{ {
@ -1414,7 +1405,7 @@ WebGLFramebuffer::FramebufferTexture2D(const char* funcName, GLenum attachEnum,
// `attachment` // `attachment`
const auto maybeAttach = GetAttachPoint(attachEnum); const auto maybeAttach = GetAttachPoint(attachEnum);
if (!maybeAttach || !maybeAttach.value()) { if (!maybeAttach || !maybeAttach.value()) {
mContext->ErrorInvalidEnum("%s: Bad `attachment`: 0x%x.", funcName, attachEnum); mContext->ErrorInvalidEnum("Bad `attachment`: 0x%x.", attachEnum);
return; return;
} }
const auto& attach = maybeAttach.value(); const auto& attach = maybeAttach.value();
@ -1424,33 +1415,31 @@ WebGLFramebuffer::FramebufferTexture2D(const char* funcName, GLenum attachEnum,
(texImageTarget < LOCAL_GL_TEXTURE_CUBE_MAP_POSITIVE_X || (texImageTarget < LOCAL_GL_TEXTURE_CUBE_MAP_POSITIVE_X ||
texImageTarget > LOCAL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Z)) texImageTarget > LOCAL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Z))
{ {
mContext->ErrorInvalidEnumInfo("framebufferTexture2D: texImageTarget:", mContext->ErrorInvalidEnumInfo("texImageTarget",
texImageTarget); texImageTarget);
return; return;
} }
// `texture` // `texture`
if (tex) { if (tex) {
if (!mContext->ValidateObject("framebufferTexture2D: texture", *tex)) if (!mContext->ValidateObject("texture", *tex))
return; return;
if (!tex->HasEverBeenBound()) { if (!tex->HasEverBeenBound()) {
mContext->ErrorInvalidOperation("%s: `texture` has never been bound.", mContext->ErrorInvalidOperation("`texture` has never been bound.");
funcName);
return; return;
} }
const TexTarget destTexTarget = TexImageTargetToTexTarget(texImageTarget); const TexTarget destTexTarget = TexImageTargetToTexTarget(texImageTarget);
if (tex->Target() != destTexTarget) { if (tex->Target() != destTexTarget) {
mContext->ErrorInvalidOperation("%s: Mismatched texture and texture target.", mContext->ErrorInvalidOperation("Mismatched texture and texture target.");
funcName);
return; return;
} }
} }
// `level` // `level`
if (level < 0) if (level < 0)
return mContext->ErrorInvalidValue("%s: `level` must not be negative.", funcName); return mContext->ErrorInvalidValue("`level` must not be negative.");
if (mContext->IsWebGL2()) { if (mContext->IsWebGL2()) {
/* GLES 3.0.4 p208: /* GLES 3.0.4 p208:
@ -1467,32 +1456,32 @@ WebGLFramebuffer::FramebufferTexture2D(const char* funcName, GLenum attachEnum,
if (texImageTarget == LOCAL_GL_TEXTURE_2D) { if (texImageTarget == LOCAL_GL_TEXTURE_2D) {
if (uint32_t(level) > FloorLog2(mContext->mGLMaxTextureSize)) if (uint32_t(level) > FloorLog2(mContext->mGLMaxTextureSize))
return mContext->ErrorInvalidValue("%s: `level` is too large.", funcName); return mContext->ErrorInvalidValue("`level` is too large.");
} else { } else {
MOZ_ASSERT(texImageTarget >= LOCAL_GL_TEXTURE_CUBE_MAP_POSITIVE_X && MOZ_ASSERT(texImageTarget >= LOCAL_GL_TEXTURE_CUBE_MAP_POSITIVE_X &&
texImageTarget <= LOCAL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Z); texImageTarget <= LOCAL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Z);
if (uint32_t(level) > FloorLog2(mContext->mGLMaxCubeMapTextureSize)) if (uint32_t(level) > FloorLog2(mContext->mGLMaxCubeMapTextureSize))
return mContext->ErrorInvalidValue("%s: `level` is too large.", funcName); return mContext->ErrorInvalidValue("`level` is too large.");
} }
} else if (level != 0) { } else if (level != 0) {
return mContext->ErrorInvalidValue("%s: `level` must be 0.", funcName); return mContext->ErrorInvalidValue("`level` must be 0.");
} }
// End of validation. // End of validation.
if (mContext->IsWebGL2() && attachEnum == LOCAL_GL_DEPTH_STENCIL_ATTACHMENT) { if (mContext->IsWebGL2() && attachEnum == LOCAL_GL_DEPTH_STENCIL_ATTACHMENT) {
mDepthAttachment.SetTexImage(funcName, tex, texImageTarget, level); mDepthAttachment.SetTexImage(tex, texImageTarget, level);
mStencilAttachment.SetTexImage(funcName, tex, texImageTarget, level); mStencilAttachment.SetTexImage(tex, texImageTarget, level);
} else { } else {
attach->SetTexImage(funcName, tex, texImageTarget, level); attach->SetTexImage(tex, texImageTarget, level);
} }
InvalidateFramebufferStatus(funcName); InvalidateFramebufferStatus();
} }
void void
WebGLFramebuffer::FramebufferTextureLayer(const char* funcName, GLenum attachEnum, WebGLFramebuffer::FramebufferTextureLayer(GLenum attachEnum,
WebGLTexture* tex, GLint level, GLint layer) WebGLTexture* tex, GLint level, GLint layer)
{ {
MOZ_ASSERT(mContext->mBoundDrawFramebuffer == this || MOZ_ASSERT(mContext->mBoundDrawFramebuffer == this ||
@ -1501,27 +1490,26 @@ WebGLFramebuffer::FramebufferTextureLayer(const char* funcName, GLenum attachEnu
// `attachment` // `attachment`
const auto maybeAttach = GetAttachPoint(attachEnum); const auto maybeAttach = GetAttachPoint(attachEnum);
if (!maybeAttach || !maybeAttach.value()) { if (!maybeAttach || !maybeAttach.value()) {
mContext->ErrorInvalidEnum("%s: Bad `attachment`: 0x%x.", funcName, attachEnum); mContext->ErrorInvalidEnum("Bad `attachment`: 0x%x.", attachEnum);
return; return;
} }
const auto& attach = maybeAttach.value(); const auto& attach = maybeAttach.value();
// `level`, `layer` // `level`, `layer`
if (layer < 0) if (layer < 0)
return mContext->ErrorInvalidValue("%s: `layer` must be >= 0.", funcName); return mContext->ErrorInvalidValue("`layer` must be >= 0.");
if (level < 0) if (level < 0)
return mContext->ErrorInvalidValue("%s: `level` must be >= 0.", funcName); return mContext->ErrorInvalidValue("`level` must be >= 0.");
// `texture` // `texture`
GLenum texImageTarget = LOCAL_GL_TEXTURE_3D; GLenum texImageTarget = LOCAL_GL_TEXTURE_3D;
if (tex) { if (tex) {
if (!mContext->ValidateObject("framebufferTextureLayer: texture", *tex)) if (!mContext->ValidateObject("texture", *tex))
return; return;
if (!tex->HasEverBeenBound()) { if (!tex->HasEverBeenBound()) {
mContext->ErrorInvalidOperation("%s: `texture` has never been bound.", mContext->ErrorInvalidOperation("`texture` has never been bound.");
funcName);
return; return;
} }
@ -1529,13 +1517,13 @@ WebGLFramebuffer::FramebufferTextureLayer(const char* funcName, GLenum attachEnu
switch (texImageTarget) { switch (texImageTarget) {
case LOCAL_GL_TEXTURE_3D: case LOCAL_GL_TEXTURE_3D:
if (uint32_t(layer) >= mContext->mGLMax3DTextureSize) { if (uint32_t(layer) >= mContext->mGLMax3DTextureSize) {
mContext->ErrorInvalidValue("%s: `layer` must be < %s.", funcName, mContext->ErrorInvalidValue("`layer` must be < %s.",
"MAX_3D_TEXTURE_SIZE"); "MAX_3D_TEXTURE_SIZE");
return; return;
} }
if (uint32_t(level) > FloorLog2(mContext->mGLMax3DTextureSize)) { if (uint32_t(level) > FloorLog2(mContext->mGLMax3DTextureSize)) {
mContext->ErrorInvalidValue("%s: `level` must be <= log2(%s).", funcName, mContext->ErrorInvalidValue("`level` must be <= log2(%s).",
"MAX_3D_TEXTURE_SIZE"); "MAX_3D_TEXTURE_SIZE");
return; return;
} }
@ -1543,22 +1531,21 @@ WebGLFramebuffer::FramebufferTextureLayer(const char* funcName, GLenum attachEnu
case LOCAL_GL_TEXTURE_2D_ARRAY: case LOCAL_GL_TEXTURE_2D_ARRAY:
if (uint32_t(layer) >= mContext->mGLMaxArrayTextureLayers) { if (uint32_t(layer) >= mContext->mGLMaxArrayTextureLayers) {
mContext->ErrorInvalidValue("%s: `layer` must be < %s.", funcName, mContext->ErrorInvalidValue("`layer` must be < %s.",
"MAX_ARRAY_TEXTURE_LAYERS"); "MAX_ARRAY_TEXTURE_LAYERS");
return; return;
} }
if (uint32_t(level) > FloorLog2(mContext->mGLMaxTextureSize)) { if (uint32_t(level) > FloorLog2(mContext->mGLMaxTextureSize)) {
mContext->ErrorInvalidValue("%s: `level` must be <= log2(%s).", funcName, mContext->ErrorInvalidValue("`level` must be <= log2(%s).",
"MAX_TEXTURE_SIZE"); "MAX_TEXTURE_SIZE");
return; return;
} }
break; break;
default: default:
mContext->ErrorInvalidOperation("%s: `texture` must be a TEXTURE_3D or" mContext->ErrorInvalidOperation("`texture` must be a TEXTURE_3D or"
" TEXTURE_2D_ARRAY.", " TEXTURE_2D_ARRAY.");
funcName);
return; return;
} }
} }
@ -1566,26 +1553,25 @@ WebGLFramebuffer::FramebufferTextureLayer(const char* funcName, GLenum attachEnu
// End of validation. // End of validation.
if (mContext->IsWebGL2() && attachEnum == LOCAL_GL_DEPTH_STENCIL_ATTACHMENT) { if (mContext->IsWebGL2() && attachEnum == LOCAL_GL_DEPTH_STENCIL_ATTACHMENT) {
mDepthAttachment.SetTexImage(funcName, tex, texImageTarget, level, layer); mDepthAttachment.SetTexImage(tex, texImageTarget, level, layer);
mStencilAttachment.SetTexImage(funcName, tex, texImageTarget, level, layer); mStencilAttachment.SetTexImage(tex, texImageTarget, level, layer);
} else { } else {
attach->SetTexImage(funcName, tex, texImageTarget, level, layer); attach->SetTexImage(tex, texImageTarget, level, layer);
} }
InvalidateFramebufferStatus(funcName); InvalidateFramebufferStatus();
} }
JS::Value JS::Value
WebGLFramebuffer::GetAttachmentParameter(const char* funcName, JSContext* cx, WebGLFramebuffer::GetAttachmentParameter(JSContext* cx,
GLenum target, GLenum attachEnum, GLenum pname, GLenum target, GLenum attachEnum, GLenum pname,
ErrorResult* const out_error) ErrorResult* const out_error)
{ {
const auto maybeAttach = GetAttachPoint(attachEnum); const auto maybeAttach = GetAttachPoint(attachEnum);
if (!maybeAttach || attachEnum == LOCAL_GL_NONE) { if (!maybeAttach || attachEnum == LOCAL_GL_NONE) {
mContext->ErrorInvalidEnum("%s: Can only query COLOR_ATTACHMENTi," mContext->ErrorInvalidEnum("Can only query COLOR_ATTACHMENTi,"
" DEPTH_ATTACHMENT, DEPTH_STENCIL_ATTACHMENT, or" " DEPTH_ATTACHMENT, DEPTH_STENCIL_ATTACHMENT, or"
" STENCIL_ATTACHMENT for a framebuffer.", " STENCIL_ATTACHMENT for a framebuffer.");
funcName);
return JS::NullValue(); return JS::NullValue();
} }
auto attach = maybeAttach.value(); auto attach = maybeAttach.value();
@ -1594,27 +1580,25 @@ WebGLFramebuffer::GetAttachmentParameter(const char* funcName, JSContext* cx,
// There are a couple special rules for this one. // There are a couple special rules for this one.
if (pname == LOCAL_GL_FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE) { if (pname == LOCAL_GL_FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE) {
mContext->ErrorInvalidOperation("%s: Querying" mContext->ErrorInvalidOperation("Querying"
" FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE" " FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE"
" against DEPTH_STENCIL_ATTACHMENT is an" " against DEPTH_STENCIL_ATTACHMENT is an"
" error.", " error.");
funcName);
return JS::NullValue(); return JS::NullValue();
} }
if (mDepthAttachment.Renderbuffer() != mStencilAttachment.Renderbuffer() || if (mDepthAttachment.Renderbuffer() != mStencilAttachment.Renderbuffer() ||
mDepthAttachment.Texture() != mStencilAttachment.Texture()) mDepthAttachment.Texture() != mStencilAttachment.Texture())
{ {
mContext->ErrorInvalidOperation("%s: DEPTH_ATTACHMENT and STENCIL_ATTACHMENT" mContext->ErrorInvalidOperation("DEPTH_ATTACHMENT and STENCIL_ATTACHMENT"
" have different objects bound.", " have different objects bound.");
funcName);
return JS::NullValue(); return JS::NullValue();
} }
attach = &mDepthAttachment; attach = &mDepthAttachment;
} }
return attach->GetParameter(funcName, mContext, cx, target, attachEnum, pname, return attach->GetParameter(mContext, cx, target, attachEnum, pname,
out_error); out_error);
} }
@ -1653,7 +1637,6 @@ WebGLFramebuffer::BlitFramebuffer(WebGLContext* webgl,
GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
GLbitfield mask, GLenum filter) GLbitfield mask, GLenum filter)
{ {
const char funcName[] = "blitFramebuffer";
const auto& gl = webgl->gl; const auto& gl = webgl->gl;
const auto& srcFB = webgl->mBoundReadFramebuffer; const auto& srcFB = webgl->mBoundReadFramebuffer;
@ -1803,17 +1786,15 @@ WebGLFramebuffer::BlitFramebuffer(WebGLContext* webgl,
if (type == webgl::ComponentType::Int || if (type == webgl::ComponentType::Int ||
type == webgl::ComponentType::UInt) type == webgl::ComponentType::UInt)
{ {
webgl->ErrorInvalidOperation("%s: `filter` is LINEAR and READ_BUFFER" webgl->ErrorInvalidOperation("`filter` is LINEAR and READ_BUFFER"
" contains integer data.", " contains integer data.");
funcName);
return; return;
} }
} }
if (!colorTypesMatch) { if (!colorTypesMatch) {
webgl->ErrorInvalidOperation("%s: Color component types (fixed/float/uint/" webgl->ErrorInvalidOperation("Color component types (fixed/float/uint/"
"int) must match.", "int) must match.");
funcName);
return; return;
} }
} }
@ -1823,9 +1804,8 @@ WebGLFramebuffer::BlitFramebuffer(WebGLContext* webgl,
if (bool(mask & depthAndStencilBits) && if (bool(mask & depthAndStencilBits) &&
filter != LOCAL_GL_NEAREST) filter != LOCAL_GL_NEAREST)
{ {
webgl->ErrorInvalidOperation("%s: DEPTH_BUFFER_BIT and STENCIL_BUFFER_BIT can" webgl->ErrorInvalidOperation("DEPTH_BUFFER_BIT and STENCIL_BUFFER_BIT can"
" only be used with NEAREST filtering.", " only be used with NEAREST filtering.");
funcName);
return; return;
} }
@ -1841,25 +1821,22 @@ WebGLFramebuffer::BlitFramebuffer(WebGLContext* webgl,
if (mask & LOCAL_GL_DEPTH_BUFFER_BIT && if (mask & LOCAL_GL_DEPTH_BUFFER_BIT &&
dstDepthFormat && dstDepthFormat != srcDepthFormat) dstDepthFormat && dstDepthFormat != srcDepthFormat)
{ {
webgl->ErrorInvalidOperation("%s: Depth buffer formats must match if selected.", webgl->ErrorInvalidOperation("Depth buffer formats must match if selected.");
funcName);
return; return;
} }
if (mask & LOCAL_GL_STENCIL_BUFFER_BIT && if (mask & LOCAL_GL_STENCIL_BUFFER_BIT &&
dstStencilFormat && dstStencilFormat != srcStencilFormat) dstStencilFormat && dstStencilFormat != srcStencilFormat)
{ {
webgl->ErrorInvalidOperation("%s: Stencil buffer formats must match if selected.", webgl->ErrorInvalidOperation("Stencil buffer formats must match if selected.");
funcName);
return; return;
} }
//// ////
if (dstHasSamples) { if (dstHasSamples) {
webgl->ErrorInvalidOperation("%s: DRAW_FRAMEBUFFER may not have multiple" webgl->ErrorInvalidOperation("DRAW_FRAMEBUFFER may not have multiple"
" samples.", " samples.");
funcName);
return; return;
} }
@ -1867,10 +1844,9 @@ WebGLFramebuffer::BlitFramebuffer(WebGLContext* webgl,
if (mask & LOCAL_GL_COLOR_BUFFER_BIT && if (mask & LOCAL_GL_COLOR_BUFFER_BIT &&
dstHasColor && !colorFormatsMatch) dstHasColor && !colorFormatsMatch)
{ {
webgl->ErrorInvalidOperation("%s: Color buffer formats must match if" webgl->ErrorInvalidOperation("Color buffer formats must match if"
" selected, when reading from a multisampled" " selected, when reading from a multisampled"
" source.", " source.");
funcName);
return; return;
} }
@ -1879,9 +1855,8 @@ WebGLFramebuffer::BlitFramebuffer(WebGLContext* webgl,
dstY0 != srcY0 || dstY0 != srcY0 ||
dstY1 != srcY1) dstY1 != srcY1)
{ {
webgl->ErrorInvalidOperation("%s: If the source is multisampled, then the" webgl->ErrorInvalidOperation("If the source is multisampled, then the"
" source and dest regions must match exactly.", " source and dest regions must match exactly.");
funcName);
return; return;
} }
} }
@ -1915,13 +1890,13 @@ WebGLFramebuffer::BlitFramebuffer(WebGLContext* webgl,
} }
if (feedback) { if (feedback) {
webgl->ErrorInvalidOperation("%s: Feedback detected into DRAW_FRAMEBUFFER's" webgl->ErrorInvalidOperation("Feedback detected into DRAW_FRAMEBUFFER's"
" 0x%04x attachment.", " 0x%04x attachment.",
funcName, feedback->mAttachmentPoint); feedback->mAttachmentPoint);
return; return;
} }
} else if (!srcFB && !dstFB) { } else if (!srcFB && !dstFB) {
webgl->ErrorInvalidOperation("%s: Feedback with default framebuffer.", funcName); webgl->ErrorInvalidOperation("Feedback with default framebuffer.");
return; return;
} }

Просмотреть файл

@ -67,11 +67,11 @@ public:
bool HasAlpha() const; bool HasAlpha() const;
bool IsReadableFloat() const; bool IsReadableFloat() const;
void Clear(const char* funcName); void Clear();
void SetTexImage(const char* funcName, WebGLTexture* tex, TexImageTarget target, void SetTexImage(WebGLTexture* tex, TexImageTarget target,
GLint level, GLint layer = 0); GLint level, GLint layer = 0);
void SetRenderbuffer(const char* funcName, WebGLRenderbuffer* rb); void SetRenderbuffer(WebGLRenderbuffer* rb);
WebGLTexture* Texture() const { return mTexturePtr; } WebGLTexture* Texture() const { return mTexturePtr; }
WebGLRenderbuffer* Renderbuffer() const { return mRenderbufferPtr; } WebGLRenderbuffer* Renderbuffer() const { return mRenderbufferPtr; }
@ -97,11 +97,11 @@ public:
void Resolve(gl::GLContext* gl) const; void Resolve(gl::GLContext* gl) const;
JS::Value GetParameter(const char* funcName, WebGLContext* webgl, JSContext* cx, JS::Value GetParameter(WebGLContext* webgl, JSContext* cx,
GLenum target, GLenum attachment, GLenum pname, GLenum target, GLenum attachment, GLenum pname,
ErrorResult* const out_error) const; ErrorResult* const out_error) const;
void OnBackingStoreRespecified(const char* funcName) const; void OnBackingStoreRespecified() const;
bool IsEquivalentForFeedback(const WebGLFBAttachPoint& other) const { bool IsEquivalentForFeedback(const WebGLFBAttachPoint& other) const {
if (!IsDefined() || !other.IsDefined()) if (!IsDefined() || !other.IsDefined())
@ -232,17 +232,16 @@ protected:
void ResolveAttachments() const; void ResolveAttachments() const;
void RefreshDrawBuffers() const; void RefreshDrawBuffers() const;
void RefreshReadBuffer() const; void RefreshReadBuffer() const;
bool ResolveAttachmentData(const char* funcName) const; bool ResolveAttachmentData() const;
public: public:
void DetachTexture(const char* funcName, const WebGLTexture* tex); void DetachTexture(const WebGLTexture* tex);
void DetachRenderbuffer(const char* funcName, const WebGLRenderbuffer* rb); void DetachRenderbuffer(const WebGLRenderbuffer* rb);
bool ValidateAndInitAttachments(const char* funcName) const; bool ValidateAndInitAttachments() const;
bool ValidateClearBufferType(const char* funcName, GLenum buffer, uint32_t drawBuffer, bool ValidateClearBufferType(GLenum buffer, uint32_t drawBuffer,
GLenum funcType) const; GLenum funcType) const;
bool ValidateForColorRead(const char* funcName, bool ValidateForColorRead(const webgl::FormatUsageInfo** out_format,
const webgl::FormatUsageInfo** out_format,
uint32_t* out_width, uint32_t* out_height) const; uint32_t* out_width, uint32_t* out_height) const;
//////////////// ////////////////
@ -279,27 +278,27 @@ public:
// Invalidation // Invalidation
bool IsResolvedComplete() const { return bool(mResolvedCompleteData); } bool IsResolvedComplete() const { return bool(mResolvedCompleteData); }
void InvalidateFramebufferStatus(const char* funcName); void InvalidateFramebufferStatus();
void RefreshResolvedData(); void RefreshResolvedData();
//////////////// ////////////////
// WebGL funcs // WebGL funcs
bool IsCheckFramebufferStatusComplete(const char* const funcName) const { bool IsCheckFramebufferStatusComplete() const {
return CheckFramebufferStatus(funcName) == LOCAL_GL_FRAMEBUFFER_COMPLETE; return CheckFramebufferStatus() == LOCAL_GL_FRAMEBUFFER_COMPLETE;
} }
FBStatus CheckFramebufferStatus(const char* funcName) const; FBStatus CheckFramebufferStatus() const;
void FramebufferRenderbuffer(const char* funcName, GLenum attachment, GLenum rbtarget, void FramebufferRenderbuffer(GLenum attachment, GLenum rbtarget,
WebGLRenderbuffer* rb); WebGLRenderbuffer* rb);
void FramebufferTexture2D(const char* funcName, GLenum attachment, void FramebufferTexture2D(GLenum attachment,
GLenum texImageTarget, WebGLTexture* tex, GLint level); GLenum texImageTarget, WebGLTexture* tex, GLint level);
void FramebufferTextureLayer(const char* funcName, GLenum attachment, void FramebufferTextureLayer(GLenum attachment,
WebGLTexture* tex, GLint level, GLint layer); WebGLTexture* tex, GLint level, GLint layer);
void DrawBuffers(const char* funcName, const dom::Sequence<GLenum>& buffers); void DrawBuffers(const dom::Sequence<GLenum>& buffers);
void ReadBuffer(const char* funcName, GLenum attachPoint); void ReadBuffer(GLenum attachPoint);
JS::Value GetAttachmentParameter(const char* funcName, JSContext* cx, GLenum target, JS::Value GetAttachmentParameter(JSContext* cx, GLenum target,
GLenum attachment, GLenum pname, GLenum attachment, GLenum pname,
ErrorResult* const out_error); ErrorResult* const out_error);

Просмотреть файл

@ -31,12 +31,12 @@ WebGLFramebufferAttachable::UnmarkAttachment(const WebGLFBAttachPoint& attachmen
} }
void void
WebGLFramebufferAttachable::InvalidateStatusOfAttachedFBs(const char* funcName) const WebGLFramebufferAttachable::InvalidateStatusOfAttachedFBs() const
{ {
const size_t count = mAttachmentPoints.Length(); const size_t count = mAttachmentPoints.Length();
for (size_t i = 0; i < count; ++i) { for (size_t i = 0; i < count; ++i) {
MOZ_ASSERT(mAttachmentPoints[i]->mFB); MOZ_ASSERT(mAttachmentPoints[i]->mFB);
mAttachmentPoints[i]->mFB->InvalidateFramebufferStatus(funcName); mAttachmentPoints[i]->mFB->InvalidateFramebufferStatus();
} }
} }

Просмотреть файл

@ -19,7 +19,7 @@ public:
// Track FBO/Attachment combinations // Track FBO/Attachment combinations
void MarkAttachment(const WebGLFBAttachPoint& attachment); void MarkAttachment(const WebGLFBAttachPoint& attachment);
void UnmarkAttachment(const WebGLFBAttachPoint& attachment); void UnmarkAttachment(const WebGLFBAttachPoint& attachment);
void InvalidateStatusOfAttachedFBs(const char* funcName) const; void InvalidateStatusOfAttachedFBs() const;
}; };
} // namespace mozilla } // namespace mozilla

Просмотреть файл

@ -463,7 +463,7 @@ webgl::LinkedProgramInfo::~LinkedProgramInfo()
} }
const webgl::CachedDrawFetchLimits* const webgl::CachedDrawFetchLimits*
webgl::LinkedProgramInfo::GetDrawFetchLimits(const char* const funcName) const webgl::LinkedProgramInfo::GetDrawFetchLimits() const
{ {
const auto& webgl = prog->mContext; const auto& webgl = prog->mContext;
const auto& vao = webgl->mBoundVertexArray; const auto& vao = webgl->mBoundVertexArray;
@ -482,9 +482,9 @@ webgl::LinkedProgramInfo::GetDrawFetchLimits(const char* const funcName) const
uint32_t i = 0; uint32_t i = 0;
for (const auto& cur : vao->mAttribs) { for (const auto& cur : vao->mAttribs) {
if (cur.mEnabled && !cur.mBuf) { if (cur.mEnabled && !cur.mBuf) {
webgl->ErrorInvalidOperation("%s: Vertex attrib array %u is enabled but" webgl->ErrorInvalidOperation("Vertex attrib array %u is enabled but"
" has no buffer bound.", " has no buffer bound.",
funcName, i); i);
return nullptr; return nullptr;
} }
} }
@ -507,9 +507,9 @@ webgl::LinkedProgramInfo::GetDrawFetchLimits(const char* const funcName) const
if (attribData.mEnabled) { if (attribData.mEnabled) {
MOZ_ASSERT(attribData.mBuf); MOZ_ASSERT(attribData.mBuf);
if (attribData.mBuf->IsBoundForTF()) { if (attribData.mBuf->IsBoundForTF()) {
webgl->ErrorInvalidOperation("%s: Vertex attrib %u's buffer is bound for" webgl->ErrorInvalidOperation("Vertex attrib %u's buffer is bound for"
" transform feedback.", " transform feedback.",
funcName, loc); loc);
return nullptr; return nullptr;
} }
cacheDeps.push_back(&attribData.mBuf->mFetchInvalidator); cacheDeps.push_back(&attribData.mBuf->mFetchInvalidator);
@ -537,18 +537,17 @@ webgl::LinkedProgramInfo::GetDrawFetchLimits(const char* const funcName) const
nsCString progType, dataType; nsCString progType, dataType;
WebGLContext::EnumName(progAttrib.mBaseType, &progType); WebGLContext::EnumName(progAttrib.mBaseType, &progType);
WebGLContext::EnumName(attribDataBaseType, &dataType); WebGLContext::EnumName(attribDataBaseType, &dataType);
webgl->ErrorInvalidOperation("%s: Vertex attrib %u requires data of type %s," webgl->ErrorInvalidOperation("Vertex attrib %u requires data of type %s,"
" but is being supplied with type %s.", " but is being supplied with type %s.",
funcName, loc, progType.BeginReading(), loc, progType.BeginReading(),
dataType.BeginReading()); dataType.BeginReading());
return nullptr; return nullptr;
} }
} }
if (hasActiveAttrib && !hasActiveDivisor0) { if (hasActiveAttrib && !hasActiveDivisor0) {
webgl->ErrorInvalidOperation("%s: One active vertex attrib (if any are active)" webgl->ErrorInvalidOperation("One active vertex attrib (if any are active)"
" must have a divisor of 0.", " must have a divisor of 0.");
funcName);
return nullptr; return nullptr;
} }
@ -625,17 +624,17 @@ WebGLProgram::AttachShader(WebGLShader* shader)
void void
WebGLProgram::BindAttribLocation(GLuint loc, const nsAString& name) WebGLProgram::BindAttribLocation(GLuint loc, const nsAString& name)
{ {
if (!ValidateGLSLVariableName(name, mContext, "bindAttribLocation")) if (!ValidateGLSLVariableName(name, mContext))
return; return;
if (loc >= mContext->MaxVertexAttribs()) { if (loc >= mContext->MaxVertexAttribs()) {
mContext->ErrorInvalidValue("bindAttribLocation: `location` must be less than" mContext->ErrorInvalidValue("`location` must be less than"
" MAX_VERTEX_ATTRIBS."); " MAX_VERTEX_ATTRIBS.");
return; return;
} }
if (StringBeginsWith(name, NS_LITERAL_STRING("gl_"))) { if (StringBeginsWith(name, NS_LITERAL_STRING("gl_"))) {
mContext->ErrorInvalidOperation("bindAttribLocation: Can't set the location of a" mContext->ErrorInvalidOperation("Can't set the location of a"
" name that starts with 'gl_'."); " name that starts with 'gl_'.");
return; return;
} }
@ -735,11 +734,11 @@ WebGLProgram::GetAttachedShaders(nsTArray<RefPtr<WebGLShader>>* const out) const
GLint GLint
WebGLProgram::GetAttribLocation(const nsAString& userName_wide) const WebGLProgram::GetAttribLocation(const nsAString& userName_wide) const
{ {
if (!ValidateGLSLVariableName(userName_wide, mContext, "getAttribLocation")) if (!ValidateGLSLVariableName(userName_wide, mContext))
return -1; return -1;
if (!IsLinked()) { if (!IsLinked()) {
mContext->ErrorInvalidOperation("getAttribLocation: `program` must be linked."); mContext->ErrorInvalidOperation("`program` must be linked.");
return -1; return -1;
} }
@ -766,11 +765,11 @@ GetFragDataByUserName(const WebGLProgram* prog,
GLint GLint
WebGLProgram::GetFragDataLocation(const nsAString& userName_wide) const WebGLProgram::GetFragDataLocation(const nsAString& userName_wide) const
{ {
if (!ValidateGLSLVariableName(userName_wide, mContext, "getFragDataLocation")) if (!ValidateGLSLVariableName(userName_wide, mContext))
return -1; return -1;
if (!IsLinked()) { if (!IsLinked()) {
mContext->ErrorInvalidOperation("getFragDataLocation: `program` must be linked."); mContext->ErrorInvalidOperation("`program` must be linked.");
return -1; return -1;
} }
@ -865,8 +864,7 @@ WebGLProgram::GetProgramParameter(GLenum pname) const
return JS::BooleanValue(bool(GetProgramiv(gl, mGLName, pname))); return JS::BooleanValue(bool(GetProgramiv(gl, mGLName, pname)));
default: default:
mContext->ErrorInvalidEnumInfo("getProgramParameter: `pname`", mContext->ErrorInvalidEnumInfo("pname", pname);
pname);
return JS::NullValue(); return JS::NullValue();
} }
} }
@ -874,11 +872,11 @@ WebGLProgram::GetProgramParameter(GLenum pname) const
GLuint GLuint
WebGLProgram::GetUniformBlockIndex(const nsAString& userName_wide) const WebGLProgram::GetUniformBlockIndex(const nsAString& userName_wide) const
{ {
if (!ValidateGLSLVariableName(userName_wide, mContext, "getUniformBlockIndex")) if (!ValidateGLSLVariableName(userName_wide, mContext))
return LOCAL_GL_INVALID_INDEX; return LOCAL_GL_INVALID_INDEX;
if (!IsLinked()) { if (!IsLinked()) {
mContext->ErrorInvalidOperation("getUniformBlockIndex: `program` must be linked."); mContext->ErrorInvalidOperation("`program` must be linked.");
return LOCAL_GL_INVALID_INDEX; return LOCAL_GL_INVALID_INDEX;
} }
@ -904,14 +902,14 @@ void
WebGLProgram::GetActiveUniformBlockName(GLuint uniformBlockIndex, nsAString& retval) const WebGLProgram::GetActiveUniformBlockName(GLuint uniformBlockIndex, nsAString& retval) const
{ {
if (!IsLinked()) { if (!IsLinked()) {
mContext->ErrorInvalidOperation("getActiveUniformBlockName: `program` must be linked."); mContext->ErrorInvalidOperation("`program` must be linked.");
return; return;
} }
const webgl::LinkedProgramInfo* linkInfo = LinkInfo(); const webgl::LinkedProgramInfo* linkInfo = LinkInfo();
GLuint uniformBlockCount = (GLuint) linkInfo->uniformBlocks.size(); GLuint uniformBlockCount = (GLuint) linkInfo->uniformBlocks.size();
if (uniformBlockIndex >= uniformBlockCount) { if (uniformBlockIndex >= uniformBlockCount) {
mContext->ErrorInvalidValue("getActiveUniformBlockName: index %u invalid.", uniformBlockIndex); mContext->ErrorInvalidValue("index %u invalid.", uniformBlockIndex);
return; return;
} }
@ -923,14 +921,14 @@ JS::Value
WebGLProgram::GetActiveUniformBlockParam(GLuint uniformBlockIndex, GLenum pname) const WebGLProgram::GetActiveUniformBlockParam(GLuint uniformBlockIndex, GLenum pname) const
{ {
if (!IsLinked()) { if (!IsLinked()) {
mContext->ErrorInvalidOperation("getActiveUniformBlockParameter: `program` must be linked."); mContext->ErrorInvalidOperation("`program` must be linked.");
return JS::NullValue(); return JS::NullValue();
} }
const webgl::LinkedProgramInfo* linkInfo = LinkInfo(); const webgl::LinkedProgramInfo* linkInfo = LinkInfo();
GLuint uniformBlockCount = (GLuint)linkInfo->uniformBlocks.size(); GLuint uniformBlockCount = (GLuint)linkInfo->uniformBlocks.size();
if (uniformBlockIndex >= uniformBlockCount) { if (uniformBlockIndex >= uniformBlockCount) {
mContext->ErrorInvalidValue("getActiveUniformBlockParameter: index %u invalid.", uniformBlockIndex); mContext->ErrorInvalidValue("Index %u invalid.", uniformBlockIndex);
return JS::NullValue(); return JS::NullValue();
} }
@ -958,16 +956,15 @@ JS::Value
WebGLProgram::GetActiveUniformBlockActiveUniforms(JSContext* cx, GLuint uniformBlockIndex, WebGLProgram::GetActiveUniformBlockActiveUniforms(JSContext* cx, GLuint uniformBlockIndex,
ErrorResult* const out_error) const ErrorResult* const out_error) const
{ {
const char funcName[] = "getActiveUniformBlockParameter";
if (!IsLinked()) { if (!IsLinked()) {
mContext->ErrorInvalidOperation("%s: `program` must be linked.", funcName); mContext->ErrorInvalidOperation("`program` must be linked.");
return JS::NullValue(); return JS::NullValue();
} }
const webgl::LinkedProgramInfo* linkInfo = LinkInfo(); const webgl::LinkedProgramInfo* linkInfo = LinkInfo();
GLuint uniformBlockCount = (GLuint)linkInfo->uniformBlocks.size(); GLuint uniformBlockCount = (GLuint)linkInfo->uniformBlocks.size();
if (uniformBlockIndex >= uniformBlockCount) { if (uniformBlockIndex >= uniformBlockCount) {
mContext->ErrorInvalidValue("%s: Index %u invalid.", funcName, uniformBlockIndex); mContext->ErrorInvalidValue("Index %u invalid.", uniformBlockIndex);
return JS::NullValue(); return JS::NullValue();
} }
@ -997,11 +994,11 @@ WebGLProgram::GetActiveUniformBlockActiveUniforms(JSContext* cx, GLuint uniformB
already_AddRefed<WebGLUniformLocation> already_AddRefed<WebGLUniformLocation>
WebGLProgram::GetUniformLocation(const nsAString& userName_wide) const WebGLProgram::GetUniformLocation(const nsAString& userName_wide) const
{ {
if (!ValidateGLSLVariableName(userName_wide, mContext, "getUniformLocation")) if (!ValidateGLSLVariableName(userName_wide, mContext))
return nullptr; return nullptr;
if (!IsLinked()) { if (!IsLinked()) {
mContext->ErrorInvalidOperation("getUniformLocation: `program` must be linked."); mContext->ErrorInvalidOperation("`program` must be linked.");
return nullptr; return nullptr;
} }
@ -1032,9 +1029,8 @@ void
WebGLProgram::GetUniformIndices(const dom::Sequence<nsString>& uniformNames, WebGLProgram::GetUniformIndices(const dom::Sequence<nsString>& uniformNames,
dom::Nullable< nsTArray<GLuint> >& retval) const dom::Nullable< nsTArray<GLuint> >& retval) const
{ {
const char funcName[] = "getUniformIndices";
if (!IsLinked()) { if (!IsLinked()) {
mContext->ErrorInvalidOperation("%s: `program` must be linked.", funcName); mContext->ErrorInvalidOperation("`program` must be linked.");
return; return;
} }
@ -1066,23 +1062,21 @@ void
WebGLProgram::UniformBlockBinding(GLuint uniformBlockIndex, WebGLProgram::UniformBlockBinding(GLuint uniformBlockIndex,
GLuint uniformBlockBinding) const GLuint uniformBlockBinding) const
{ {
const char funcName[] = "getActiveUniformBlockName";
if (!IsLinked()) { if (!IsLinked()) {
mContext->ErrorInvalidOperation("%s: `program` must be linked.", funcName); mContext->ErrorInvalidOperation("`program` must be linked.");
return; return;
} }
const auto& uniformBlocks = LinkInfo()->uniformBlocks; const auto& uniformBlocks = LinkInfo()->uniformBlocks;
if (uniformBlockIndex >= uniformBlocks.size()) { if (uniformBlockIndex >= uniformBlocks.size()) {
mContext->ErrorInvalidValue("%s: Index %u invalid.", funcName, uniformBlockIndex); mContext->ErrorInvalidValue("Index %u invalid.", uniformBlockIndex);
return; return;
} }
const auto& uniformBlock = uniformBlocks[uniformBlockIndex]; const auto& uniformBlock = uniformBlocks[uniformBlockIndex];
const auto& indexedBindings = mContext->mIndexedUniformBufferBindings; const auto& indexedBindings = mContext->mIndexedUniformBufferBindings;
if (uniformBlockBinding >= indexedBindings.size()) { if (uniformBlockBinding >= indexedBindings.size()) {
mContext->ErrorInvalidValue("%s: Binding %u invalid.", funcName, mContext->ErrorInvalidValue("Binding %u invalid.", uniformBlockBinding);
uniformBlockBinding);
return; return;
} }
const auto& indexedBinding = indexedBindings[uniformBlockBinding]; const auto& indexedBinding = indexedBindings[uniformBlockBinding];
@ -1142,12 +1136,9 @@ WebGLProgram::ValidateForLink()
void void
WebGLProgram::LinkProgram() WebGLProgram::LinkProgram()
{ {
const char funcName[] = "linkProgram";
if (mNumActiveTFOs) { if (mNumActiveTFOs) {
mContext->ErrorInvalidOperation("%s: Program is in-use by one or more active" mContext->ErrorInvalidOperation("Program is in-use by one or more active"
" transform feedback objects.", " transform feedback objects.");
funcName);
return; return;
} }
@ -1157,7 +1148,7 @@ WebGLProgram::LinkProgram()
mMostRecentLinkInfo = nullptr; mMostRecentLinkInfo = nullptr;
if (!ValidateForLink()) { if (!ValidateForLink()) {
mContext->GenerateWarning("%s: %s", funcName, mLinkLog.BeginReading()); mContext->GenerateWarning("%s", mLinkLog.BeginReading());
return; return;
} }
@ -1208,7 +1199,7 @@ WebGLProgram::LinkProgram()
// report in compileShader the translation errors generated by ANGLE, // report in compileShader the translation errors generated by ANGLE,
// but it seems saner to keep a single way of obtaining shader infologs. // but it seems saner to keep a single way of obtaining shader infologs.
if (!mLinkLog.IsEmpty()) { if (!mLinkLog.IsEmpty()) {
mContext->GenerateWarning("linkProgram: Failed to link, leaving the following" mContext->GenerateWarning("Failed to link, leaving the following"
" log:\n%s\n", " log:\n%s\n",
mLinkLog.BeginReading()); mLinkLog.BeginReading());
} }
@ -1427,11 +1418,8 @@ WebGLProgram::ValidateAfterTentativeLink(nsCString* const out_linkLog) const
bool bool
WebGLProgram::UseProgram() const WebGLProgram::UseProgram() const
{ {
const char funcName[] = "useProgram";
if (!mMostRecentLinkInfo) { if (!mMostRecentLinkInfo) {
mContext->ErrorInvalidOperation("%s: Program has not been successfully linked.", mContext->ErrorInvalidOperation("Program has not been successfully linked.");
funcName);
return false; return false;
} }
@ -1439,8 +1427,7 @@ WebGLProgram::UseProgram() const
mContext->mBoundTransformFeedback->mIsActive && mContext->mBoundTransformFeedback->mIsActive &&
!mContext->mBoundTransformFeedback->mIsPaused) !mContext->mBoundTransformFeedback->mIsPaused)
{ {
mContext->ErrorInvalidOperation("%s: Transform feedback active and not paused.", mContext->ErrorInvalidOperation("Transform feedback active and not paused.");
funcName);
return false; return false;
} }
@ -1457,7 +1444,7 @@ WebGLProgram::ValidateProgram() const
// See bug 593867 for NVIDIA and bug 657201 for ATI. The latter is confirmed // See bug 593867 for NVIDIA and bug 657201 for ATI. The latter is confirmed
// with Mac OS 10.6.7. // with Mac OS 10.6.7.
if (gl->WorkAroundDriverBugs()) { if (gl->WorkAroundDriverBugs()) {
mContext->GenerateWarning("validateProgram: Implemented as a no-op on" mContext->GenerateWarning("Implemented as a no-op on"
" Mac to work around crashes."); " Mac to work around crashes.");
return; return;
} }
@ -1536,8 +1523,6 @@ void
WebGLProgram::TransformFeedbackVaryings(const dom::Sequence<nsString>& varyings, WebGLProgram::TransformFeedbackVaryings(const dom::Sequence<nsString>& varyings,
GLenum bufferMode) GLenum bufferMode)
{ {
const char funcName[] = "transformFeedbackVaryings";
const auto& gl = mContext->gl; const auto& gl = mContext->gl;
switch (bufferMode) { switch (bufferMode) {
@ -1550,8 +1535,7 @@ WebGLProgram::TransformFeedbackVaryings(const dom::Sequence<nsString>& varyings,
gl->GetUIntegerv(LOCAL_GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS, gl->GetUIntegerv(LOCAL_GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS,
&maxAttribs); &maxAttribs);
if (varyings.Length() > maxAttribs) { if (varyings.Length() > maxAttribs) {
mContext->ErrorInvalidValue("%s: Length of `varyings` exceeds %s.", mContext->ErrorInvalidValue("Length of `varyings` exceeds %s.",
funcName,
"TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS"); "TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS");
return; return;
} }
@ -1559,7 +1543,7 @@ WebGLProgram::TransformFeedbackVaryings(const dom::Sequence<nsString>& varyings,
break; break;
default: default:
mContext->ErrorInvalidEnum("%s: Bad `bufferMode`: 0x%04x.", funcName, bufferMode); mContext->ErrorInvalidEnumInfo("bufferMode", bufferMode);
return; return;
} }
@ -1576,13 +1560,12 @@ WebGLProgram::GetTransformFeedbackVarying(GLuint index) const
// No docs in the WebGL 2 spec for this function. Taking the language for // No docs in the WebGL 2 spec for this function. Taking the language for
// getActiveAttrib, which states that the function returns null on any error. // getActiveAttrib, which states that the function returns null on any error.
if (!IsLinked()) { if (!IsLinked()) {
mContext->ErrorInvalidOperation("getTransformFeedbackVarying: `program` must be " mContext->ErrorInvalidOperation("`program` must be linked.");
"linked.");
return nullptr; return nullptr;
} }
if (index >= LinkInfo()->transformFeedbackVaryings.size()) { if (index >= LinkInfo()->transformFeedbackVaryings.size()) {
mContext->ErrorInvalidValue("getTransformFeedbackVarying: `index` is greater or " mContext->ErrorInvalidValue("`index` is greater or "
"equal to TRANSFORM_FEEDBACK_VARYINGS."); "equal to TRANSFORM_FEEDBACK_VARYINGS.");
return nullptr; return nullptr;
} }

Просмотреть файл

@ -117,7 +117,7 @@ struct LinkedProgramInfo final
mutable CacheMap<const WebGLVertexArray*, mutable CacheMap<const WebGLVertexArray*,
CachedDrawFetchLimits> mDrawFetchCache; CachedDrawFetchLimits> mDrawFetchCache;
const CachedDrawFetchLimits* GetDrawFetchLimits(const char* funcName) const; const CachedDrawFetchLimits* GetDrawFetchLimits() const;
////// //////

Просмотреть файл

@ -65,10 +65,8 @@ TargetForDriver(const gl::GLContext* gl, GLenum target)
void void
WebGLQuery::BeginQuery(GLenum target, WebGLRefPtr<WebGLQuery>& slot) WebGLQuery::BeginQuery(GLenum target, WebGLRefPtr<WebGLQuery>& slot)
{ {
const char funcName[] = "beginQuery";
if (mTarget && target != mTarget) { if (mTarget && target != mTarget) {
mContext->ErrorInvalidOperation("%s: Queries cannot change targets.", funcName); mContext->ErrorInvalidOperation("Queries cannot change targets.");
return; return;
} }
@ -109,25 +107,23 @@ WebGLQuery::EndQuery()
void void
WebGLQuery::GetQueryParameter(GLenum pname, JS::MutableHandleValue retval) const WebGLQuery::GetQueryParameter(GLenum pname, JS::MutableHandleValue retval) const
{ {
const char funcName[] = "getQueryParameter";
switch (pname) { switch (pname) {
case LOCAL_GL_QUERY_RESULT_AVAILABLE: case LOCAL_GL_QUERY_RESULT_AVAILABLE:
case LOCAL_GL_QUERY_RESULT: case LOCAL_GL_QUERY_RESULT:
break; break;
default: default:
mContext->ErrorInvalidEnumArg(funcName, "pname", pname); mContext->ErrorInvalidEnumInfo("pname", pname);
return; return;
} }
if (!mTarget) { if (!mTarget) {
mContext->ErrorInvalidOperation("%s: Query has never been active.", funcName); mContext->ErrorInvalidOperation("Query has never been active.");
return; return;
} }
if (mActiveSlot) if (mActiveSlot)
return mContext->ErrorInvalidOperation("%s: Query is still active.", funcName); return mContext->ErrorInvalidOperation("Query is still active.");
// End of validation // End of validation
//// ////
@ -208,15 +204,15 @@ WebGLQuery::DeleteQuery()
} }
void void
WebGLQuery::QueryCounter(const char* funcName, GLenum target) WebGLQuery::QueryCounter(GLenum target)
{ {
if (target != LOCAL_GL_TIMESTAMP_EXT) { if (target != LOCAL_GL_TIMESTAMP_EXT) {
mContext->ErrorInvalidEnum("%s: `target` must be TIMESTAMP_EXT.", funcName); mContext->ErrorInvalidEnum("`target` must be TIMESTAMP_EXT.");
return; return;
} }
if (mTarget && target != mTarget) { if (mTarget && target != mTarget) {
mContext->ErrorInvalidOperation("%s: Queries cannot change targets.", funcName); mContext->ErrorInvalidOperation("Queries cannot change targets.");
return; return;
} }

Просмотреть файл

@ -64,7 +64,7 @@ public:
void EndQuery(); void EndQuery();
void GetQueryParameter(GLenum pname, JS::MutableHandleValue retval) const; void GetQueryParameter(GLenum pname, JS::MutableHandleValue retval) const;
bool IsQuery() const; bool IsQuery() const;
void QueryCounter(const char* funcName, GLenum target); void QueryCounter(GLenum target);
}; };
} // namespace mozilla } // namespace mozilla

Просмотреть файл

@ -175,13 +175,12 @@ WebGLRenderbuffer::DoRenderbufferStorage(uint32_t samples,
} }
void void
WebGLRenderbuffer::RenderbufferStorage(const char* funcName, uint32_t samples, WebGLRenderbuffer::RenderbufferStorage(uint32_t samples, GLenum internalFormat,
GLenum internalFormat, uint32_t width, uint32_t width, uint32_t height)
uint32_t height)
{ {
const auto usage = mContext->mFormatUsage->GetRBUsage(internalFormat); const auto usage = mContext->mFormatUsage->GetRBUsage(internalFormat);
if (!usage) { if (!usage) {
mContext->ErrorInvalidEnum("%s: Invalid `internalFormat`: 0x%04x.", funcName, mContext->ErrorInvalidEnum("Invalid `internalFormat`: 0x%04x.",
internalFormat); internalFormat);
return; return;
} }
@ -189,9 +188,8 @@ WebGLRenderbuffer::RenderbufferStorage(const char* funcName, uint32_t samples,
if (width > mContext->mGLMaxRenderbufferSize || if (width > mContext->mGLMaxRenderbufferSize ||
height > mContext->mGLMaxRenderbufferSize) height > mContext->mGLMaxRenderbufferSize)
{ {
mContext->ErrorInvalidValue("%s: Width or height exceeds maximum renderbuffer" mContext->ErrorInvalidValue("Width or height exceeds maximum renderbuffer"
" size.", " size.");
funcName);
return; return;
} }
@ -201,7 +199,7 @@ WebGLRenderbuffer::RenderbufferStorage(const char* funcName, uint32_t samples,
MOZ_ASSERT(usage->maxSamplesKnown); MOZ_ASSERT(usage->maxSamplesKnown);
if (samples > usage->maxSamples) { if (samples > usage->maxSamples) {
mContext->ErrorInvalidOperation("%s: `samples` is out of the valid range.", funcName); mContext->ErrorInvalidOperation("`samples` is out of the valid range.");
return; return;
} }
@ -209,8 +207,7 @@ WebGLRenderbuffer::RenderbufferStorage(const char* funcName, uint32_t samples,
const GLenum error = DoRenderbufferStorage(samples, usage, width, height); const GLenum error = DoRenderbufferStorage(samples, usage, width, height);
if (error) { if (error) {
const char* errorName = WebGLContext::ErrorName(error); mContext->GenerateWarning("Unexpected error %s", EnumString(error).c_str());
mContext->GenerateWarning("%s generated error %s", funcName, errorName);
return; return;
} }
@ -222,7 +219,7 @@ WebGLRenderbuffer::RenderbufferStorage(const char* funcName, uint32_t samples,
mHeight = height; mHeight = height;
mImageDataStatus = WebGLImageDataStatus::UninitializedImageData; mImageDataStatus = WebGLImageDataStatus::UninitializedImageData;
InvalidateStatusOfAttachedFBs(funcName); InvalidateStatusOfAttachedFBs();
} }
void void

Просмотреть файл

@ -72,8 +72,8 @@ public:
return mContext; return mContext;
} }
void RenderbufferStorage(const char* funcName, uint32_t samples, void RenderbufferStorage(uint32_t samples, GLenum internalFormat, uint32_t width,
GLenum internalFormat, uint32_t width, uint32_t height); uint32_t height);
// Only handles a subset of `pname`s. // Only handles a subset of `pname`s.
GLint GetRenderbufferParameter(RBTarget target, RBParam pname) const; GLint GetRenderbufferParameter(RBTarget target, RBParam pname) const;

Просмотреть файл

@ -50,7 +50,7 @@ WebGLSampler::WrapObject(JSContext* cx, JS::Handle<JSObject*> givenProto)
} }
static bool static bool
ValidateSamplerParameterParams(WebGLContext* webgl, const char* funcName, GLenum pname, ValidateSamplerParameterParams(WebGLContext* webgl, GLenum pname,
const FloatOrInt& param) const FloatOrInt& param)
{ {
const auto& paramInt = param.i; const auto& paramInt = param.i;
@ -129,19 +129,18 @@ ValidateSamplerParameterParams(WebGLContext* webgl, const char* funcName, GLenum
break; break;
default: default:
webgl->ErrorInvalidEnumArg(funcName, "pname", pname); webgl->ErrorInvalidEnumInfo("pname", pname);
return false; return false;
} }
webgl->ErrorInvalidEnumArg(funcName, "param", paramInt); webgl->ErrorInvalidEnumInfo("param", paramInt);
return false; return false;
} }
void void
WebGLSampler::SamplerParameter(const char* funcName, GLenum pname, WebGLSampler::SamplerParameter(GLenum pname, const FloatOrInt& param)
const FloatOrInt& param)
{ {
if (!ValidateSamplerParameterParams(mContext, funcName, pname, param)) if (!ValidateSamplerParameterParams(mContext, pname, param))
return; return;
switch (pname) { switch (pname) {

Просмотреть файл

@ -41,7 +41,7 @@ public:
virtual JSObject* WrapObject(JSContext* cx, JS::Handle<JSObject*> givenProto) override; virtual JSObject* WrapObject(JSContext* cx, JS::Handle<JSObject*> givenProto) override;
void SamplerParameter(const char* funcName, GLenum pname, const FloatOrInt& param); void SamplerParameter(GLenum pname, const FloatOrInt& param);
const auto& State() const { return mState; } const auto& State() const { return mState; }
}; };

Просмотреть файл

@ -172,15 +172,13 @@ WebGLShader::~WebGLShader()
void void
WebGLShader::ShaderSource(const nsAString& source) WebGLShader::ShaderSource(const nsAString& source)
{ {
const char funcName[] = "shaderSource";
nsString sourceWithoutComments; nsString sourceWithoutComments;
if (!TruncateComments(source, &sourceWithoutComments)) { if (!TruncateComments(source, &sourceWithoutComments)) {
mContext->ErrorOutOfMemory("%s: Failed to alloc for empting comment contents.", mContext->ErrorOutOfMemory("Failed to alloc for empting comment contents.");
funcName);
return; return;
} }
if (!ValidateGLSLPreprocString(mContext, funcName, sourceWithoutComments)) if (!ValidateGLSLPreprocString(mContext, sourceWithoutComments))
return; return;
// We checked that the source stripped of comments is in the // We checked that the source stripped of comments is in the

Просмотреть файл

@ -33,12 +33,12 @@ Mutable(const T& x)
} }
void void
WebGLTexture::ImageInfo::Clear(const char* funcName) WebGLTexture::ImageInfo::Clear()
{ {
if (!IsDefined()) if (!IsDefined())
return; return;
OnRespecify(funcName); OnRespecify();
Mutable(mFormat) = LOCAL_GL_NONE; Mutable(mFormat) = LOCAL_GL_NONE;
Mutable(mWidth) = 0; Mutable(mWidth) = 0;
@ -49,7 +49,7 @@ WebGLTexture::ImageInfo::Clear(const char* funcName)
} }
void void
WebGLTexture::ImageInfo::Set(const char* funcName, const ImageInfo& a) WebGLTexture::ImageInfo::Set(const ImageInfo& a)
{ {
MOZ_ASSERT(a.IsDefined()); MOZ_ASSERT(a.IsDefined());
@ -62,7 +62,7 @@ WebGLTexture::ImageInfo::Set(const char* funcName, const ImageInfo& a)
// But *don't* transfer mAttachPoints! // But *don't* transfer mAttachPoints!
MOZ_ASSERT(a.mAttachPoints.empty()); MOZ_ASSERT(a.mAttachPoints.empty());
OnRespecify(funcName); OnRespecify();
} }
bool bool
@ -89,10 +89,10 @@ WebGLTexture::ImageInfo::RemoveAttachPoint(WebGLFBAttachPoint* attachPoint)
} }
void void
WebGLTexture::ImageInfo::OnRespecify(const char* funcName) const WebGLTexture::ImageInfo::OnRespecify() const
{ {
for (auto cur : mAttachPoints) { for (auto cur : mAttachPoints) {
cur->OnBackingStoreRespecified(funcName); cur->OnBackingStoreRespecified();
} }
} }
@ -143,9 +143,8 @@ WebGLTexture::WebGLTexture(WebGLContext* webgl, GLuint tex)
void void
WebGLTexture::Delete() WebGLTexture::Delete()
{ {
const char funcName[] = "WebGLTexture::Delete";
for (auto& cur : mImageInfoArr) { for (auto& cur : mImageInfoArr) {
cur.Clear(funcName); cur.Clear();
} }
mContext->gl->fDeleteTextures(1, &mGLName); mContext->gl->fDeleteTextures(1, &mGLName);
@ -167,27 +166,27 @@ WebGLTexture::MemoryUsage() const
} }
void void
WebGLTexture::SetImageInfo(const char* funcName, ImageInfo* target, WebGLTexture::SetImageInfo(ImageInfo* target,
const ImageInfo& newInfo) const ImageInfo& newInfo)
{ {
target->Set(funcName, newInfo); target->Set(newInfo);
InvalidateResolveCache(); InvalidateResolveCache();
} }
void void
WebGLTexture::SetImageInfosAtLevel(const char* funcName, uint32_t level, WebGLTexture::SetImageInfosAtLevel(uint32_t level,
const ImageInfo& newInfo) const ImageInfo& newInfo)
{ {
for (uint8_t i = 0; i < mFaceCount; i++) { for (uint8_t i = 0; i < mFaceCount; i++) {
ImageInfoAtFace(i, level).Set(funcName, newInfo); ImageInfoAtFace(i, level).Set(newInfo);
} }
InvalidateResolveCache(); InvalidateResolveCache();
} }
bool bool
WebGLTexture::IsMipmapComplete(const char* funcName, uint32_t texUnit, WebGLTexture::IsMipmapComplete(uint32_t texUnit,
bool* const out_initFailed) bool* const out_initFailed)
{ {
*out_initFailed = false; *out_initFailed = false;
@ -211,7 +210,7 @@ WebGLTexture::IsMipmapComplete(const char* funcName, uint32_t texUnit,
MOZ_ASSERT(refWidth && refHeight && refDepth); MOZ_ASSERT(refWidth && refHeight && refDepth);
for (uint32_t level = mBaseMipmapLevel; level <= maxLevel; level++) { for (uint32_t level = mBaseMipmapLevel; level <= maxLevel; level++) {
if (!EnsureLevelInitialized(funcName, level)) { if (!EnsureLevelInitialized(level)) {
*out_initFailed = true; *out_initFailed = true;
return false; return false;
} }
@ -303,7 +302,7 @@ WebGLTexture::IsCubeComplete() const
} }
bool bool
WebGLTexture::IsComplete(const char* funcName, uint32_t texUnit, WebGLTexture::IsComplete(uint32_t texUnit,
const char** const out_reason, bool* const out_initFailed) const char** const out_reason, bool* const out_initFailed)
{ {
*out_initFailed = false; *out_initFailed = false;
@ -350,7 +349,7 @@ WebGLTexture::IsComplete(const char* funcName, uint32_t texUnit,
// the texture is not mipmap complete." // the texture is not mipmap complete."
const bool requiresMipmap = (minFilter != LOCAL_GL_NEAREST && const bool requiresMipmap = (minFilter != LOCAL_GL_NEAREST &&
minFilter != LOCAL_GL_LINEAR); minFilter != LOCAL_GL_LINEAR);
if (requiresMipmap && !IsMipmapComplete(funcName, texUnit, out_initFailed)) { if (requiresMipmap && !IsMipmapComplete(texUnit, out_initFailed)) {
if (*out_initFailed) if (*out_initFailed)
return false; return false;
@ -444,7 +443,7 @@ WebGLTexture::IsComplete(const char* funcName, uint32_t texUnit,
// (already covered) // (already covered)
} }
if (!EnsureLevelInitialized(funcName, mBaseMipmapLevel)) { if (!EnsureLevelInitialized(mBaseMipmapLevel)) {
*out_initFailed = true; *out_initFailed = true;
return false; return false;
} }
@ -480,23 +479,22 @@ WebGLTexture::MaxEffectiveMipmapLevel(uint32_t texUnit, uint32_t* const out) con
} }
bool bool
WebGLTexture::GetFakeBlackType(const char* funcName, uint32_t texUnit, WebGLTexture::GetFakeBlackType(uint32_t texUnit,
FakeBlackType* const out_fakeBlack) FakeBlackType* const out_fakeBlack)
{ {
const char* incompleteReason; const char* incompleteReason;
bool initFailed = false; bool initFailed = false;
if (!IsComplete(funcName, texUnit, &incompleteReason, &initFailed)) { if (!IsComplete(texUnit, &incompleteReason, &initFailed)) {
if (initFailed) { if (initFailed) {
mContext->ErrorOutOfMemory("%s: Failed to initialize texture data.", mContext->ErrorOutOfMemory("Failed to initialize texture data.");
funcName);
return false; // The world just exploded. return false; // The world just exploded.
} }
if (incompleteReason) { if (incompleteReason) {
mContext->GenerateWarning("%s: Active texture %u for target 0x%04x is" mContext->GenerateWarning("Active texture %u for target 0x%04x is"
" 'incomplete', and will be rendered as" " 'incomplete', and will be rendered as"
" RGBA(0,0,0,1), as per the GLES 2.0.24 $3.8.2: %s", " RGBA(0,0,0,1), as per the GLES 2.0.24 $3.8.2: %s",
funcName, texUnit, mTarget.get(), texUnit, mTarget.get(),
incompleteReason); incompleteReason);
} }
*out_fakeBlack = FakeBlackType::RGBA0001; *out_fakeBlack = FakeBlackType::RGBA0001;
@ -526,11 +524,11 @@ SetSwizzle(gl::GLContext* gl, TexTarget target, const GLint* swizzle)
} }
bool bool
WebGLTexture::ResolveForDraw(const char* funcName, uint32_t texUnit, WebGLTexture::ResolveForDraw(uint32_t texUnit,
FakeBlackType* const out_fakeBlack) FakeBlackType* const out_fakeBlack)
{ {
if (!mIsResolved) { if (!mIsResolved) {
if (!GetFakeBlackType(funcName, texUnit, &mResolved_FakeBlack)) if (!GetFakeBlackType(texUnit, &mResolved_FakeBlack))
return false; return false;
// Check which swizzle we should use. Since the texture must be complete at this // Check which swizzle we should use. Since the texture must be complete at this
@ -559,7 +557,7 @@ WebGLTexture::ResolveForDraw(const char* funcName, uint32_t texUnit,
} }
bool bool
WebGLTexture::EnsureImageDataInitialized(const char* funcName, TexImageTarget target, WebGLTexture::EnsureImageDataInitialized(TexImageTarget target,
uint32_t level) uint32_t level)
{ {
auto& imageInfo = ImageInfoAt(target, level); auto& imageInfo = ImageInfoAt(target, level);
@ -569,20 +567,20 @@ WebGLTexture::EnsureImageDataInitialized(const char* funcName, TexImageTarget ta
if (imageInfo.IsDataInitialized()) if (imageInfo.IsDataInitialized())
return true; return true;
return InitializeImageData(funcName, target, level); return InitializeImageData(target, level);
} }
bool bool
WebGLTexture::EnsureLevelInitialized(const char* funcName, uint32_t level) WebGLTexture::EnsureLevelInitialized(uint32_t level)
{ {
if (mTarget != LOCAL_GL_TEXTURE_CUBE_MAP) if (mTarget != LOCAL_GL_TEXTURE_CUBE_MAP)
return EnsureImageDataInitialized(funcName, mTarget.get(), level); return EnsureImageDataInitialized(mTarget.get(), level);
for (GLenum texImageTarget = LOCAL_GL_TEXTURE_CUBE_MAP_POSITIVE_X; for (GLenum texImageTarget = LOCAL_GL_TEXTURE_CUBE_MAP_POSITIVE_X;
texImageTarget <= LOCAL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Z; texImageTarget <= LOCAL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Z;
++texImageTarget) ++texImageTarget)
{ {
if (!EnsureImageDataInitialized(funcName, texImageTarget, level)) if (!EnsureImageDataInitialized(texImageTarget, level))
return false; return false;
} }
return true; return true;
@ -630,7 +628,7 @@ ZeroANGLEDepthTexture(WebGLContext* webgl, GLuint tex,
} }
static bool static bool
ZeroTextureData(WebGLContext* webgl, const char* funcName, GLuint tex, ZeroTextureData(WebGLContext* webgl, GLuint tex,
TexImageTarget target, uint32_t level, TexImageTarget target, uint32_t level,
const webgl::FormatUsageInfo* usage, uint32_t width, uint32_t height, const webgl::FormatUsageInfo* usage, uint32_t width, uint32_t height,
uint32_t depth) uint32_t depth)
@ -644,9 +642,8 @@ ZeroTextureData(WebGLContext* webgl, const char* funcName, GLuint tex,
// We have no sympathy for any of these cases. // We have no sympathy for any of these cases.
// "Doctor, it hurts when I do this!" "Well don't do that!" // "Doctor, it hurts when I do this!" "Well don't do that!"
webgl->GenerateWarning("%s: This operation requires zeroing texture data. This is" webgl->GenerateWarning("This operation requires zeroing texture data. This is"
" slow.", " slow.");
funcName);
gl::GLContext* gl = webgl->GL(); gl::GLContext* gl = webgl->GL();
@ -742,7 +739,7 @@ ZeroTextureData(WebGLContext* webgl, const char* funcName, GLuint tex,
} }
bool bool
WebGLTexture::InitializeImageData(const char* funcName, TexImageTarget target, WebGLTexture::InitializeImageData(TexImageTarget target,
uint32_t level) uint32_t level)
{ {
auto& imageInfo = ImageInfoAt(target, level); auto& imageInfo = ImageInfoAt(target, level);
@ -754,7 +751,7 @@ WebGLTexture::InitializeImageData(const char* funcName, TexImageTarget target,
const auto& height = imageInfo.mHeight; const auto& height = imageInfo.mHeight;
const auto& depth = imageInfo.mDepth; const auto& depth = imageInfo.mDepth;
if (!ZeroTextureData(mContext, funcName, mGLName, target, level, usage, width, height, if (!ZeroTextureData(mContext, mGLName, target, level, usage, width, height,
depth)) depth))
{ {
return false; return false;
@ -781,7 +778,7 @@ WebGLTexture::ClampLevelBaseAndMax()
} }
void void
WebGLTexture::PopulateMipChain(const char* funcName, uint32_t firstLevel, WebGLTexture::PopulateMipChain(uint32_t firstLevel,
uint32_t lastLevel) uint32_t lastLevel)
{ {
const ImageInfo& baseImageInfo = ImageInfoAtFace(0, firstLevel); const ImageInfo& baseImageInfo = ImageInfoAtFace(0, firstLevel);
@ -813,7 +810,7 @@ WebGLTexture::PopulateMipChain(const char* funcName, uint32_t firstLevel,
const ImageInfo cur(baseImageInfo.mFormat, refWidth, refHeight, refDepth, const ImageInfo cur(baseImageInfo.mFormat, refWidth, refHeight, refDepth,
baseImageInfo.IsDataInitialized()); baseImageInfo.IsDataInitialized());
SetImageInfosAtLevel(funcName, level, cur); SetImageInfosAtLevel(level, cur);
} }
} }
@ -862,8 +859,7 @@ WebGLTexture::BindTexture(TexTarget texTarget)
void void
WebGLTexture::GenerateMipmap(TexTarget texTarget) WebGLTexture::GenerateMipmap(TexTarget texTarget)
{ {\
const char funcName[] = "generateMipmap";
// GLES 3.0.4 p160: // GLES 3.0.4 p160:
// "Mipmap generation replaces texel array levels level base + 1 through q with arrays // "Mipmap generation replaces texel array levels level base + 1 through q with arrays
// derived from the level base array, regardless of their previous contents. All // derived from the level base array, regardless of their previous contents. All
@ -871,43 +867,37 @@ WebGLTexture::GenerateMipmap(TexTarget texTarget)
// computation." // computation."
const ImageInfo& baseImageInfo = BaseImageInfo(); const ImageInfo& baseImageInfo = BaseImageInfo();
if (!baseImageInfo.IsDefined()) { if (!baseImageInfo.IsDefined()) {
mContext->ErrorInvalidOperation("%s: The base level of the texture is not" mContext->ErrorInvalidOperation("The base level of the texture is not"
" defined.", " defined.");
funcName);
return; return;
} }
if (IsCubeMap() && !IsCubeComplete()) { if (IsCubeMap() && !IsCubeComplete()) {
mContext->ErrorInvalidOperation("%s: Cube maps must be \"cube complete\".", mContext->ErrorInvalidOperation("Cube maps must be \"cube complete\".");
funcName);
return; return;
} }
const auto format = baseImageInfo.mFormat->format; const auto format = baseImageInfo.mFormat->format;
if (!mContext->IsWebGL2()) { if (!mContext->IsWebGL2()) {
if (!baseImageInfo.IsPowerOfTwo()) { if (!baseImageInfo.IsPowerOfTwo()) {
mContext->ErrorInvalidOperation("%s: The base level of the texture does not" mContext->ErrorInvalidOperation("The base level of the texture does not"
" have power-of-two dimensions.", " have power-of-two dimensions.");
funcName);
return; return;
} }
if (format->isSRGB) { if (format->isSRGB) {
mContext->ErrorInvalidOperation("%s: EXT_sRGB forbids GenerateMipmap with" mContext->ErrorInvalidOperation("EXT_sRGB forbids GenerateMipmap with"
" sRGB.", " sRGB.");
funcName);
return; return;
} }
} }
if (format->compression) { if (format->compression) {
mContext->ErrorInvalidOperation("%s: Texture data at base level is compressed.", mContext->ErrorInvalidOperation("Texture data at base level is compressed.");
funcName);
return; return;
} }
if (format->d) { if (format->d) {
mContext->ErrorInvalidOperation("%s: Depth textures are not supported.", mContext->ErrorInvalidOperation("Depth textures are not supported.");
funcName);
return; return;
} }
@ -930,10 +920,9 @@ WebGLTexture::GenerateMipmap(TexTarget texTarget)
} }
if (!canGenerateMipmap) { if (!canGenerateMipmap) {
mContext->ErrorInvalidOperation("%s: Texture at base level is not unsized" mContext->ErrorInvalidOperation("Texture at base level is not unsized"
" internal format or is not" " internal format or is not"
" color-renderable or texture-filterable.", " color-renderable or texture-filterable.");
funcName);
return; return;
} }
@ -960,7 +949,7 @@ WebGLTexture::GenerateMipmap(TexTarget texTarget)
// Note that we don't use MaxEffectiveMipmapLevel() here, since that returns // Note that we don't use MaxEffectiveMipmapLevel() here, since that returns
// mBaseMipmapLevel if the min filter doesn't require mipmaps. // mBaseMipmapLevel if the min filter doesn't require mipmaps.
const uint32_t maxLevel = mBaseMipmapLevel + baseImageInfo.PossibleMipmapLevels() - 1; const uint32_t maxLevel = mBaseMipmapLevel + baseImageInfo.PossibleMipmapLevels() - 1;
PopulateMipChain(funcName, mBaseMipmapLevel, maxLevel); PopulateMipChain(mBaseMipmapLevel, maxLevel);
} }
JS::Value JS::Value
@ -1135,11 +1124,11 @@ WebGLTexture::TexParameter(TexTarget texTarget, GLenum pname, const FloatOrInt&
if (paramBadEnum) { if (paramBadEnum) {
if (!param.isFloat) { if (!param.isFloat) {
mContext->ErrorInvalidEnum("texParameteri: pname 0x%04x: Invalid param" mContext->ErrorInvalidEnum("pname 0x%04x: Invalid param"
" 0x%04x.", " 0x%04x.",
pname, param.i); pname, param.i);
} else { } else {
mContext->ErrorInvalidEnum("texParameterf: pname 0x%04x: Invalid param %g.", mContext->ErrorInvalidEnum("pname 0x%04x: Invalid param %g.",
pname, param.f); pname, param.f);
} }
return; return;
@ -1147,11 +1136,11 @@ WebGLTexture::TexParameter(TexTarget texTarget, GLenum pname, const FloatOrInt&
if (paramBadValue) { if (paramBadValue) {
if (!param.isFloat) { if (!param.isFloat) {
mContext->ErrorInvalidValue("texParameteri: pname 0x%04x: Invalid param %i" mContext->ErrorInvalidValue("pname 0x%04x: Invalid param %i"
" (0x%x).", " (0x%x).",
pname, param.i, param.i); pname, param.i, param.i);
} else { } else {
mContext->ErrorInvalidValue("texParameterf: pname 0x%04x: Invalid param %g.", mContext->ErrorInvalidValue("pname 0x%04x: Invalid param %g.",
pname, param.f); pname, param.f);
} }
return; return;

Просмотреть файл

@ -48,8 +48,7 @@ class TexUnpackBlob;
bool bool
DoesTargetMatchDimensions(WebGLContext* webgl, TexImageTarget target, uint8_t dims, DoesTargetMatchDimensions(WebGLContext* webgl, TexImageTarget target, uint8_t dims);
const char* funcName);
namespace webgl { namespace webgl {
@ -118,19 +117,17 @@ public:
// And in turn, it needs these forwards: // And in turn, it needs these forwards:
protected: protected:
// We need to forward these. // We need to forward these.
void SetImageInfo(const char* funcName, ImageInfo* target, const ImageInfo& newInfo); void SetImageInfo(ImageInfo* target, const ImageInfo& newInfo);
void SetImageInfosAtLevel(const char* funcName, uint32_t level, void SetImageInfosAtLevel(uint32_t level, const ImageInfo& newInfo);
const ImageInfo& newInfo);
public: public:
// We store information about the various images that are part of this // We store information about the various images that are part of this
// texture. (cubemap faces, mipmap levels) // texture. (cubemap faces, mipmap levels)
class ImageInfo class ImageInfo
{ {
friend void WebGLTexture::SetImageInfo(const char* funcName, ImageInfo* target, friend void WebGLTexture::SetImageInfo(ImageInfo* target,
const ImageInfo& newInfo); const ImageInfo& newInfo);
friend void WebGLTexture::SetImageInfosAtLevel(const char* funcName, friend void WebGLTexture::SetImageInfosAtLevel(uint32_t level,
uint32_t level,
const ImageInfo& newInfo); const ImageInfo& newInfo);
public: public:
@ -170,14 +167,14 @@ public:
MOZ_ASSERT(mFormat); MOZ_ASSERT(mFormat);
} }
void Clear(const char* funcName); void Clear();
~ImageInfo() { ~ImageInfo() {
MOZ_ASSERT(!mAttachPoints.size()); MOZ_ASSERT(!mAttachPoints.size());
} }
protected: protected:
void Set(const char* funcName, const ImageInfo& a); void Set(const ImageInfo& a);
public: public:
uint32_t PossibleMipmapLevels() const { uint32_t PossibleMipmapLevels() const {
@ -191,7 +188,7 @@ public:
void AddAttachPoint(WebGLFBAttachPoint* attachPoint); void AddAttachPoint(WebGLFBAttachPoint* attachPoint);
void RemoveAttachPoint(WebGLFBAttachPoint* attachPoint); void RemoveAttachPoint(WebGLFBAttachPoint* attachPoint);
void OnRespecify(const char* funcName) const; void OnRespecify() const;
size_t MemoryUsage() const; size_t MemoryUsage() const;
@ -247,55 +244,55 @@ public:
// WebGLTextureUpload.cpp // WebGLTextureUpload.cpp
protected: protected:
void TexOrSubImageBlob(bool isSubImage, const char* funcName, TexImageTarget target, void TexOrSubImageBlob(bool isSubImage, TexImageTarget target,
GLint level, GLenum internalFormat, GLint xOffset, GLint level, GLenum internalFormat, GLint xOffset,
GLint yOffset, GLint zOffset, GLint yOffset, GLint zOffset,
const webgl::PackingInfo& pi, const webgl::PackingInfo& pi,
const webgl::TexUnpackBlob* blob); const webgl::TexUnpackBlob* blob);
bool ValidateTexImageSpecification(const char* funcName, TexImageTarget target, bool ValidateTexImageSpecification(TexImageTarget target,
GLint level, uint32_t width, uint32_t height, GLint level, uint32_t width, uint32_t height,
uint32_t depth, uint32_t depth,
WebGLTexture::ImageInfo** const out_imageInfo); WebGLTexture::ImageInfo** const out_imageInfo);
bool ValidateTexImageSelection(const char* funcName, TexImageTarget target, bool ValidateTexImageSelection(TexImageTarget target,
GLint level, GLint xOffset, GLint yOffset, GLint level, GLint xOffset, GLint yOffset,
GLint zOffset, uint32_t width, uint32_t height, GLint zOffset, uint32_t width, uint32_t height,
uint32_t depth, uint32_t depth,
WebGLTexture::ImageInfo** const out_imageInfo); WebGLTexture::ImageInfo** const out_imageInfo);
bool ValidateCopyTexImageForFeedback(const char* funcName, uint32_t level, GLint layer = 0) const; bool ValidateCopyTexImageForFeedback(uint32_t level, GLint layer = 0) const;
bool ValidateUnpack(const char* funcName, const webgl::TexUnpackBlob* blob, bool ValidateUnpack(const webgl::TexUnpackBlob* blob,
bool isFunc3D, const webgl::PackingInfo& srcPI) const; bool isFunc3D, const webgl::PackingInfo& srcPI) const;
public: public:
void TexStorage(const char* funcName, TexTarget target, GLsizei levels, void TexStorage(TexTarget target, GLsizei levels,
GLenum sizedFormat, GLsizei width, GLsizei height, GLsizei depth); GLenum sizedFormat, GLsizei width, GLsizei height, GLsizei depth);
void TexImage(const char* funcName, TexImageTarget target, GLint level, void TexImage(TexImageTarget target, GLint level,
GLenum internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLenum internalFormat, GLsizei width, GLsizei height, GLsizei depth,
GLint border, const webgl::PackingInfo& pi, const TexImageSource& src); GLint border, const webgl::PackingInfo& pi, const TexImageSource& src);
void TexSubImage(const char* funcName, TexImageTarget target, GLint level, void TexSubImage(TexImageTarget target, GLint level,
GLint xOffset, GLint yOffset, GLint zOffset, GLsizei width, GLint xOffset, GLint yOffset, GLint zOffset, GLsizei width,
GLsizei height, GLsizei depth, const webgl::PackingInfo& pi, GLsizei height, GLsizei depth, const webgl::PackingInfo& pi,
const TexImageSource& src); const TexImageSource& src);
protected: protected:
void TexImage(const char* funcName, TexImageTarget target, GLint level, void TexImage(TexImageTarget target, GLint level,
GLenum internalFormat, const webgl::PackingInfo& pi, GLenum internalFormat, const webgl::PackingInfo& pi,
const webgl::TexUnpackBlob* blob); const webgl::TexUnpackBlob* blob);
void TexSubImage(const char* funcName, TexImageTarget target, GLint level, void TexSubImage(TexImageTarget target, GLint level,
GLint xOffset, GLint yOffset, GLint zOffset, GLint xOffset, GLint yOffset, GLint zOffset,
const webgl::PackingInfo& pi, const webgl::TexUnpackBlob* blob); const webgl::PackingInfo& pi, const webgl::TexUnpackBlob* blob);
public: public:
void CompressedTexImage(const char* funcName, TexImageTarget target, GLint level, void CompressedTexImage(TexImageTarget target, GLint level,
GLenum internalFormat, GLsizei width, GLsizei height, GLenum internalFormat, GLsizei width, GLsizei height,
GLsizei depth, GLint border, const TexImageSource& src, GLsizei depth, GLint border, const TexImageSource& src,
const Maybe<GLsizei>& expectedImageSize); const Maybe<GLsizei>& expectedImageSize);
void CompressedTexSubImage(const char* funcName, TexImageTarget target, GLint level, void CompressedTexSubImage(TexImageTarget target, GLint level,
GLint xOffset, GLint yOffset, GLint zOffset, GLsizei width, GLint xOffset, GLint yOffset, GLint zOffset, GLsizei width,
GLsizei height, GLsizei depth, GLenum sizedUnpackFormat, GLsizei height, GLsizei depth, GLenum sizedUnpackFormat,
const TexImageSource& src, const Maybe<GLsizei>& expectedImageSize); const TexImageSource& src, const Maybe<GLsizei>& expectedImageSize);
void CopyTexImage2D(TexImageTarget target, GLint level, GLenum internalFormat, void CopyTexImage2D(TexImageTarget target, GLint level, GLenum internalFormat,
GLint x, GLint y, GLsizei width, GLsizei height, GLint border); GLint x, GLint y, GLsizei width, GLsizei height, GLint border);
void CopyTexSubImage(const char* funcName, TexImageTarget target, GLint level, void CopyTexSubImage(TexImageTarget target, GLint level,
GLint xOffset, GLint yOffset, GLint zOffset, GLint x, GLint y, GLint xOffset, GLint yOffset, GLint zOffset, GLint x, GLint y,
GLsizei width, GLsizei height); GLsizei width, GLsizei height);
@ -304,7 +301,7 @@ public:
protected: protected:
void ClampLevelBaseAndMax(); void ClampLevelBaseAndMax();
void PopulateMipChain(const char* funcName, uint32_t baseLevel, uint32_t maxLevel); void PopulateMipChain(uint32_t baseLevel, uint32_t maxLevel);
bool MaxEffectiveMipmapLevel(uint32_t texUnit, uint32_t* const out) const; bool MaxEffectiveMipmapLevel(uint32_t texUnit, uint32_t* const out) const;
@ -345,11 +342,11 @@ public:
return const_cast<WebGLTexture*>(this)->ImageInfoAt(texImageTarget, level); return const_cast<WebGLTexture*>(this)->ImageInfoAt(texImageTarget, level);
} }
void SetImageInfoAt(const char* funcName, TexImageTarget texImageTarget, GLint level, void SetImageInfoAt(TexImageTarget texImageTarget, GLint level,
const ImageInfo& val) const ImageInfo& val)
{ {
ImageInfo* target = &ImageInfoAt(texImageTarget, level); ImageInfo* target = &ImageInfoAt(texImageTarget, level);
SetImageInfo(funcName, target, val); SetImageInfo(target, val);
} }
const ImageInfo& BaseImageInfo() const { const ImageInfo& BaseImageInfo() const {
@ -361,11 +358,11 @@ public:
size_t MemoryUsage() const; size_t MemoryUsage() const;
bool InitializeImageData(const char* funcName, TexImageTarget target, uint32_t level); bool InitializeImageData(TexImageTarget target, uint32_t level);
protected: protected:
bool EnsureImageDataInitialized(const char* funcName, TexImageTarget target, bool EnsureImageDataInitialized(TexImageTarget target,
uint32_t level); uint32_t level);
bool EnsureLevelInitialized(const char* funcName, uint32_t level); bool EnsureLevelInitialized(uint32_t level);
public: public:
void SetGeneratedMipmap(); void SetGeneratedMipmap();
@ -374,12 +371,12 @@ public:
bool AreAllLevel0ImageInfosEqual() const; bool AreAllLevel0ImageInfosEqual() const;
bool IsMipmapComplete(const char* funcName, uint32_t texUnit, bool IsMipmapComplete(uint32_t texUnit,
bool* const out_initFailed); bool* const out_initFailed);
bool IsCubeComplete() const; bool IsCubeComplete() const;
bool IsComplete(const char* funcName, uint32_t texUnit, const char** const out_reason, bool IsComplete(uint32_t texUnit, const char** const out_reason,
bool* const out_initFailed); bool* const out_initFailed);
bool IsMipmapCubeComplete() const; bool IsMipmapCubeComplete() const;
@ -388,13 +385,13 @@ public:
// Resolve cache optimizations // Resolve cache optimizations
protected: protected:
bool GetFakeBlackType(const char* funcName, uint32_t texUnit, bool GetFakeBlackType(uint32_t texUnit,
FakeBlackType* const out_fakeBlack); FakeBlackType* const out_fakeBlack);
public: public:
bool IsFeedback(WebGLContext* webgl, const char* funcName, uint32_t texUnit, bool IsFeedback(WebGLContext* webgl, uint32_t texUnit,
const std::vector<const WebGLFBAttachPoint*>& fbAttachments) const; const std::vector<const WebGLFBAttachPoint*>& fbAttachments) const;
bool ResolveForDraw(const char* funcName, uint32_t texUnit, bool ResolveForDraw(uint32_t texUnit,
FakeBlackType* const out_fakeBlack); FakeBlackType* const out_fakeBlack);
void InvalidateResolveCache() { mIsResolved = false; } void InvalidateResolveCache() { mIsResolved = false; }

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -41,10 +41,8 @@ WebGLTransformFeedback::Delete()
void void
WebGLTransformFeedback::BeginTransformFeedback(GLenum primMode) WebGLTransformFeedback::BeginTransformFeedback(GLenum primMode)
{ {
const char funcName[] = "beginTransformFeedback";
if (mIsActive) if (mIsActive)
return mContext->ErrorInvalidOperation("%s: Already active.", funcName); return mContext->ErrorInvalidOperation("Already active.");
switch (primMode) { switch (primMode) {
case LOCAL_GL_POINTS: case LOCAL_GL_POINTS:
@ -52,9 +50,8 @@ WebGLTransformFeedback::BeginTransformFeedback(GLenum primMode)
case LOCAL_GL_TRIANGLES: case LOCAL_GL_TRIANGLES:
break; break;
default: default:
mContext->ErrorInvalidEnum("%s: `primitiveMode` must be one of POINTS, LINES, or" mContext->ErrorInvalidEnum("`primitiveMode` must be one of POINTS, LINES, or"
" TRIANGLES.", " TRIANGLES.");
funcName);
return; return;
} }
@ -63,9 +60,8 @@ WebGLTransformFeedback::BeginTransformFeedback(GLenum primMode)
!prog->IsLinked() || !prog->IsLinked() ||
prog->LinkInfo()->componentsPerTFVert.empty()) prog->LinkInfo()->componentsPerTFVert.empty())
{ {
mContext->ErrorInvalidOperation("%s: Current program not valid for transform" mContext->ErrorInvalidOperation("Current program not valid for transform"
" feedback.", " feedback.");
funcName);
return; return;
} }
@ -79,9 +75,9 @@ WebGLTransformFeedback::BeginTransformFeedback(GLenum primMode)
const auto& buffer = indexedBinding.mBufferBinding; const auto& buffer = indexedBinding.mBufferBinding;
if (!buffer) { if (!buffer) {
mContext->ErrorInvalidOperation("%s: No buffer attached to required transform" mContext->ErrorInvalidOperation("No buffer attached to required transform"
" feedback index %u.", " feedback index %u.",
funcName, (uint32_t)i); (uint32_t)i);
return; return;
} }
@ -113,10 +109,8 @@ WebGLTransformFeedback::BeginTransformFeedback(GLenum primMode)
void void
WebGLTransformFeedback::EndTransformFeedback() WebGLTransformFeedback::EndTransformFeedback()
{ {
const char funcName[] = "endTransformFeedback";
if (!mIsActive) if (!mIsActive)
return mContext->ErrorInvalidOperation("%s: Not active.", funcName); return mContext->ErrorInvalidOperation("Not active.");
//// ////
@ -148,12 +142,10 @@ WebGLTransformFeedback::EndTransformFeedback()
void void
WebGLTransformFeedback::PauseTransformFeedback() WebGLTransformFeedback::PauseTransformFeedback()
{ {
const char funcName[] = "pauseTransformFeedback";
if (!mIsActive || if (!mIsActive ||
mIsPaused) mIsPaused)
{ {
mContext->ErrorInvalidOperation("%s: Not active or is paused.", funcName); mContext->ErrorInvalidOperation("Not active or is paused.");
return; return;
} }
@ -170,14 +162,11 @@ WebGLTransformFeedback::PauseTransformFeedback()
void void
WebGLTransformFeedback::ResumeTransformFeedback() WebGLTransformFeedback::ResumeTransformFeedback()
{ {
const char funcName[] = "resumeTransformFeedback";
if (!mIsPaused) if (!mIsPaused)
return mContext->ErrorInvalidOperation("%s: Not paused.", funcName); return mContext->ErrorInvalidOperation("Not paused.");
if (mContext->mCurrentProgram != mActive_Program) { if (mContext->mCurrentProgram != mActive_Program) {
mContext->ErrorInvalidOperation("%s: Active program differs from original.", mContext->ErrorInvalidOperation("Active program differs from original.");
funcName);
return; return;
} }

Просмотреть файл

@ -26,7 +26,7 @@ class WebGLTransformFeedback final
friend class WebGLProgram; friend class WebGLProgram;
friend const webgl::CachedDrawFetchLimits* friend const webgl::CachedDrawFetchLimits*
ValidateDraw(WebGLContext*, const char*, GLenum, uint32_t); ValidateDraw(WebGLContext*, GLenum, uint32_t);
public: public:
const GLuint mGLName; const GLuint mGLName;

Просмотреть файл

@ -29,20 +29,18 @@ WebGLUniformLocation::~WebGLUniformLocation()
{ } { }
bool bool
WebGLUniformLocation::ValidateForProgram(const WebGLProgram* prog, WebGLUniformLocation::ValidateForProgram(const WebGLProgram* prog) const
const char* funcName) const
{ {
// Check the weak-pointer. // Check the weak-pointer.
if (!mLinkInfo) { if (!mLinkInfo) {
mContext->ErrorInvalidOperation("%s: This uniform location is obsolete because" mContext->ErrorInvalidOperation("This uniform location is obsolete because"
" its program has been successfully relinked.", " its program has been successfully relinked.");
funcName);
return false; return false;
} }
if (mLinkInfo->prog != prog) { if (mLinkInfo->prog != prog) {
mContext->ErrorInvalidOperation("%s: This uniform location corresponds to a" mContext->ErrorInvalidOperation("This uniform location corresponds to a"
" different program.", funcName); " different program.");
return false; return false;
} }
@ -119,23 +117,22 @@ IsUniformSetterTypeValid(GLenum setterType, GLenum uniformType)
} }
bool bool
WebGLUniformLocation::ValidateSizeAndType(uint8_t setterElemSize, GLenum setterType, WebGLUniformLocation::ValidateSizeAndType(uint8_t setterElemSize, GLenum setterType) const
const char* funcName) const
{ {
MOZ_ASSERT(mLinkInfo); MOZ_ASSERT(mLinkInfo);
const auto& uniformElemSize = mInfo->mActiveInfo->mElemSize; const auto& uniformElemSize = mInfo->mActiveInfo->mElemSize;
if (setterElemSize != uniformElemSize) { if (setterElemSize != uniformElemSize) {
mContext->ErrorInvalidOperation("%s: Function used differs from uniform size: %i", mContext->ErrorInvalidOperation("Function used differs from uniform size: %i",
funcName, uniformElemSize); uniformElemSize);
return false; return false;
} }
const auto& uniformElemType = mInfo->mActiveInfo->mElemType; const auto& uniformElemType = mInfo->mActiveInfo->mElemType;
if (!IsUniformSetterTypeValid(setterType, uniformElemType)) { if (!IsUniformSetterTypeValid(setterType, uniformElemType)) {
mContext->ErrorInvalidOperation("%s: Function used is incompatible with uniform" mContext->ErrorInvalidOperation("Function used is incompatible with uniform"
" type: %i", " type: %i",
funcName, uniformElemType); uniformElemType);
return false; return false;
} }
@ -143,17 +140,17 @@ WebGLUniformLocation::ValidateSizeAndType(uint8_t setterElemSize, GLenum setterT
} }
bool bool
WebGLUniformLocation::ValidateArrayLength(uint8_t setterElemSize, size_t setterArraySize, WebGLUniformLocation::ValidateArrayLength(uint8_t setterElemSize,
const char* funcName) const size_t setterArraySize) const
{ {
MOZ_ASSERT(mLinkInfo); MOZ_ASSERT(mLinkInfo);
if (setterArraySize == 0 || if (setterArraySize == 0 ||
setterArraySize % setterElemSize) setterArraySize % setterElemSize)
{ {
mContext->ErrorInvalidValue("%s: Expected an array of length a multiple of %d," mContext->ErrorInvalidValue("Expected an array of length a multiple of %d,"
" got an array of length %zu.", " got an array of length %zu.",
funcName, setterElemSize, setterArraySize); setterElemSize, setterArraySize);
return false; return false;
} }
@ -167,10 +164,10 @@ WebGLUniformLocation::ValidateArrayLength(uint8_t setterElemSize, size_t setterA
if (!mInfo->mActiveInfo->mIsArray && if (!mInfo->mActiveInfo->mIsArray &&
setterArraySize != setterElemSize) setterArraySize != setterElemSize)
{ {
mContext->ErrorInvalidOperation("%s: Expected an array of length exactly %d" mContext->ErrorInvalidOperation("Expected an array of length exactly %d"
" (since this uniform is not an array uniform)," " (since this uniform is not an array uniform),"
" got an array of length %zu.", " got an array of length %zu.",
funcName, setterElemSize, setterArraySize); setterElemSize, setterArraySize);
return false; return false;
} }

Просмотреть файл

@ -52,11 +52,9 @@ public:
WebGLUniformLocation(WebGLContext* webgl, const webgl::LinkedProgramInfo* linkInfo, WebGLUniformLocation(WebGLContext* webgl, const webgl::LinkedProgramInfo* linkInfo,
webgl::UniformInfo* info, GLuint loc, size_t arrayIndex); webgl::UniformInfo* info, GLuint loc, size_t arrayIndex);
bool ValidateForProgram(const WebGLProgram* prog, const char* funcName) const; bool ValidateForProgram(const WebGLProgram* prog) const;
bool ValidateSizeAndType(uint8_t setterElemSize, GLenum setterType, bool ValidateSizeAndType(uint8_t setterElemSize, GLenum setterType) const;
const char* funcName) const; bool ValidateArrayLength(uint8_t setterElemSize, size_t setterArraySize) const;
bool ValidateArrayLength(uint8_t setterElemSize, size_t setterArraySize,
const char* funcName) const;
JS::Value GetUniform(JSContext* js) const; JS::Value GetUniform(JSContext* js) const;

Просмотреть файл

@ -174,22 +174,20 @@ IsValidGLSLPreprocChar(char16_t c)
//// ////
bool bool
ValidateGLSLPreprocString(WebGLContext* webgl, const char* funcName, ValidateGLSLPreprocString(WebGLContext* webgl, const nsAString& string)
const nsAString& string)
{ {
for (size_t i = 0; i < string.Length(); ++i) { for (size_t i = 0; i < string.Length(); ++i) {
const auto& cur = string[i]; const auto& cur = string[i];
if (!IsValidGLSLPreprocChar(cur)) { if (!IsValidGLSLPreprocChar(cur)) {
webgl->ErrorInvalidValue("%s: String contains the illegal character 0x%x.", webgl->ErrorInvalidValue("String contains the illegal character 0x%x.", cur);
funcName, cur);
return false; return false;
} }
if (cur == '\\' && !webgl->IsWebGL2()) { if (cur == '\\' && !webgl->IsWebGL2()) {
// Todo: Backslash is technically still invalid in WebGLSL 1 under even under // Todo: Backslash is technically still invalid in WebGLSL 1 under even under
// WebGL 2. // WebGL 2.
webgl->ErrorInvalidValue("%s: Backslash is not valid in WebGL 1.", funcName); webgl->ErrorInvalidValue("Backslash is not valid in WebGL 1.");
return false; return false;
} }
} }
@ -198,24 +196,23 @@ ValidateGLSLPreprocString(WebGLContext* webgl, const char* funcName,
} }
bool bool
ValidateGLSLVariableName(const nsAString& name, WebGLContext* webgl, const char* funcName) ValidateGLSLVariableName(const nsAString& name, WebGLContext* webgl)
{ {
if (name.IsEmpty()) if (name.IsEmpty())
return false; return false;
const uint32_t maxSize = webgl->IsWebGL2() ? 1024 : 256; const uint32_t maxSize = webgl->IsWebGL2() ? 1024 : 256;
if (name.Length() > maxSize) { if (name.Length() > maxSize) {
webgl->ErrorInvalidValue("%s: Identifier is %u characters long, exceeds the" webgl->ErrorInvalidValue("Identifier is %u characters long, exceeds the"
" maximum allowed length of %u characters.", " maximum allowed length of %u characters.",
funcName, name.Length(), maxSize); name.Length(), maxSize);
return false; return false;
} }
for (size_t i = 0; i < name.Length(); ++i) { for (size_t i = 0; i < name.Length(); ++i) {
const auto& cur = name[i]; const auto& cur = name[i];
if (!IsValidGLSLChar(cur)) { if (!IsValidGLSLChar(cur)) {
webgl->ErrorInvalidValue("%s: String contains the illegal character 0x%x'.", webgl->ErrorInvalidValue("String contains the illegal character 0x%x'.", cur);
funcName, cur);
return false; return false;
} }
} }
@ -226,8 +223,7 @@ ValidateGLSLVariableName(const nsAString& name, WebGLContext* webgl, const char*
if (Substring(name, 0, prefix1.Length()).Equals(prefix1) || if (Substring(name, 0, prefix1.Length()).Equals(prefix1) ||
Substring(name, 0, prefix2.Length()).Equals(prefix2)) Substring(name, 0, prefix2.Length()).Equals(prefix2))
{ {
webgl->ErrorInvalidOperation("%s: String contains a reserved GLSL prefix.", webgl->ErrorInvalidOperation("String contains a reserved GLSL prefix.");
funcName);
return false; return false;
} }

Просмотреть файл

@ -36,11 +36,9 @@ class WebGLContext;
bool bool
TruncateComments(const nsAString& src, nsAString* const out); TruncateComments(const nsAString& src, nsAString* const out);
bool bool
ValidateGLSLPreprocString(WebGLContext* webgl, const char* funcName, ValidateGLSLPreprocString(WebGLContext* webgl, const nsAString& string);
const nsAString& string);
bool bool
ValidateGLSLVariableName(const nsAString& name, WebGLContext* webgl, ValidateGLSLVariableName(const nsAString& name, WebGLContext* webgl);
const char* funcName);
} // namespace mozilla } // namespace mozilla