зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1478909 - Make funcName implicit for WebGL calls. - r=kvark
MozReview-Commit-ID: Gv77SnHZcGb
This commit is contained in:
Родитель
14af3949fc
Коммит
8e0436b208
|
@ -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
|
||||||
|
|
||||||
|
|
Загрузка…
Ссылка в новой задаче