b=573705; fix computation of texel sizes and refactor WebGLenum validation functions; r=vladimir

This commit is contained in:
Benoit Jacob 2010-06-30 11:49:59 -04:00
parent f1886bd4e3
commit a5df0a74df
3 changed files with 134 additions and 157 deletions

View File

@ -290,6 +290,9 @@ public:
nsresult ErrorInvalidEnum(const char *fmt = 0, ...); nsresult ErrorInvalidEnum(const char *fmt = 0, ...);
nsresult ErrorInvalidOperation(const char *fmt = 0, ...); nsresult ErrorInvalidOperation(const char *fmt = 0, ...);
nsresult ErrorInvalidValue(const char *fmt = 0, ...); nsresult ErrorInvalidValue(const char *fmt = 0, ...);
nsresult ErrorInvalidEnumInfo(const char *info) {
return ErrorInvalidEnum("%s: invalid enum value", info);
}
already_AddRefed<CanvasLayer> GetCanvasLayer(LayerManager *manager); already_AddRefed<CanvasLayer> GetCanvasLayer(LayerManager *manager);
void MarkContextClean() { } void MarkContextClean() { }
@ -316,14 +319,16 @@ protected:
PRBool SafeToCreateCanvas3DContext(nsHTMLCanvasElement *canvasElement); PRBool SafeToCreateCanvas3DContext(nsHTMLCanvasElement *canvasElement);
PRBool InitAndValidateGL(); PRBool InitAndValidateGL();
PRBool ValidateBuffers(PRUint32 count); PRBool ValidateBuffers(PRUint32 count);
static PRBool ValidateCapabilityEnum(WebGLenum cap); PRBool ValidateCapabilityEnum(WebGLenum cap, const char *info);
static PRBool ValidateBlendEquationEnum(WebGLuint cap); PRBool ValidateBlendEquationEnum(WebGLuint cap, const char *info);
static PRBool ValidateBlendFuncDstEnum(WebGLuint mode); PRBool ValidateBlendFuncDstEnum(WebGLuint mode, const char *info);
static PRBool ValidateBlendFuncSrcEnum(WebGLuint mode); PRBool ValidateBlendFuncSrcEnum(WebGLuint mode, const char *info);
static PRBool ValidateTextureTargetEnum(WebGLenum target); PRBool ValidateTextureTargetEnum(WebGLenum target, const char *info);
static PRBool ValidateComparisonEnum(WebGLenum target); PRBool ValidateComparisonEnum(WebGLenum target, const char *info);
static PRBool ValidateStencilOpEnum(WebGLenum action); PRBool ValidateStencilOpEnum(WebGLenum action, const char *info);
static PRBool ValidateFaceEnum(WebGLenum target); PRBool ValidateFaceEnum(WebGLenum target, const char *info);
PRBool ValidateTexFormatAndType(WebGLenum format, WebGLenum type,
PRUint32 *texelSize, const char *info);
void Invalidate(); void Invalidate();

View File

@ -296,8 +296,8 @@ GL_SAME_METHOD_4(BlendColor, BlendColor, float, float, float, float)
NS_IMETHODIMP WebGLContext::BlendEquation(WebGLenum mode) NS_IMETHODIMP WebGLContext::BlendEquation(WebGLenum mode)
{ {
if (!ValidateBlendEquationEnum(mode)) if (!ValidateBlendEquationEnum(mode, "blendEquation: mode"))
return ErrorInvalidEnum("BlendEquation: invalid mode"); return NS_OK;
MakeContextCurrent(); MakeContextCurrent();
gl->fBlendEquation(mode); gl->fBlendEquation(mode);
@ -306,9 +306,9 @@ NS_IMETHODIMP WebGLContext::BlendEquation(WebGLenum mode)
NS_IMETHODIMP WebGLContext::BlendEquationSeparate(WebGLenum modeRGB, WebGLenum modeAlpha) NS_IMETHODIMP WebGLContext::BlendEquationSeparate(WebGLenum modeRGB, WebGLenum modeAlpha)
{ {
if (!ValidateBlendEquationEnum(modeRGB) || if (!ValidateBlendEquationEnum(modeRGB, "blendEquationSeparate: modeRGB") ||
!ValidateBlendEquationEnum(modeAlpha)) !ValidateBlendEquationEnum(modeAlpha, "blendEquationSeparate: modeAlpha"))
return ErrorInvalidEnum("BlendEquationSeparate: invalid mode"); return NS_OK;
MakeContextCurrent(); MakeContextCurrent();
gl->fBlendEquationSeparate(modeRGB, modeAlpha); gl->fBlendEquationSeparate(modeRGB, modeAlpha);
@ -317,10 +317,9 @@ NS_IMETHODIMP WebGLContext::BlendEquationSeparate(WebGLenum modeRGB, WebGLenum m
NS_IMETHODIMP WebGLContext::BlendFunc(WebGLenum sfactor, WebGLenum dfactor) NS_IMETHODIMP WebGLContext::BlendFunc(WebGLenum sfactor, WebGLenum dfactor)
{ {
if (!ValidateBlendFuncSrcEnum(sfactor)) if (!ValidateBlendFuncSrcEnum(sfactor, "blendFunc: sfactor") ||
return ErrorInvalidEnum("BlendFunc: invalid source factor"); !ValidateBlendFuncDstEnum(dfactor, "blendFunc: dfactor"))
if (!ValidateBlendFuncDstEnum(dfactor)) return NS_OK;
return ErrorInvalidEnum("BlendFunc: invalid destination factor");
MakeContextCurrent(); MakeContextCurrent();
gl->fBlendFunc(sfactor, dfactor); gl->fBlendFunc(sfactor, dfactor);
@ -331,12 +330,11 @@ NS_IMETHODIMP
WebGLContext::BlendFuncSeparate(WebGLenum srcRGB, WebGLenum dstRGB, WebGLContext::BlendFuncSeparate(WebGLenum srcRGB, WebGLenum dstRGB,
WebGLenum srcAlpha, WebGLenum dstAlpha) WebGLenum srcAlpha, WebGLenum dstAlpha)
{ {
if (!ValidateBlendFuncSrcEnum(srcRGB) || if (!ValidateBlendFuncSrcEnum(srcRGB, "blendFuncSeparate: srcRGB") ||
!ValidateBlendFuncSrcEnum(srcAlpha)) !ValidateBlendFuncSrcEnum(srcAlpha, "blendFuncSeparate: srcAlpha") ||
return ErrorInvalidEnum("BlendFuncSeparate: invalid source factor"); !ValidateBlendFuncDstEnum(dstRGB, "blendFuncSeparate: dstRGB") ||
if (!ValidateBlendFuncDstEnum(dstRGB) || !ValidateBlendFuncDstEnum(dstAlpha, "blendFuncSeparate: dstAlpha"))
!ValidateBlendFuncDstEnum(dstAlpha)) return NS_OK;
return ErrorInvalidEnum("BlendFuncSeparate: invalid destination factor");
MakeContextCurrent(); MakeContextCurrent();
gl->fBlendFuncSeparate(srcRGB, dstRGB, srcAlpha, dstAlpha); gl->fBlendFuncSeparate(srcRGB, dstRGB, srcAlpha, dstAlpha);
@ -807,8 +805,8 @@ WebGLContext::DetachShader(nsIWebGLProgram *pobj, nsIWebGLShader *shobj)
NS_IMETHODIMP NS_IMETHODIMP
WebGLContext::DepthFunc(WebGLenum func) WebGLContext::DepthFunc(WebGLenum func)
{ {
if (!ValidateComparisonEnum(func)) if (!ValidateComparisonEnum(func, "depthFunc"))
return ErrorInvalidEnum("DepthFunc: invalid function enum"); return NS_OK;
MakeContextCurrent(); MakeContextCurrent();
gl->fDepthFunc(func); gl->fDepthFunc(func);
@ -955,8 +953,8 @@ WebGLContext::DrawElements(WebGLenum mode, WebGLsizei count, WebGLenum type, Web
NS_IMETHODIMP WebGLContext::Enable(WebGLenum cap) NS_IMETHODIMP WebGLContext::Enable(WebGLenum cap)
{ {
if (!ValidateCapabilityEnum(cap)) if (!ValidateCapabilityEnum(cap, "enable"))
return ErrorInvalidEnum("Enable: invalid capability enum"); return NS_OK;
MakeContextCurrent(); MakeContextCurrent();
gl->fEnable(cap); gl->fEnable(cap);
@ -965,8 +963,8 @@ NS_IMETHODIMP WebGLContext::Enable(WebGLenum cap)
NS_IMETHODIMP WebGLContext::Disable(WebGLenum cap) NS_IMETHODIMP WebGLContext::Disable(WebGLenum cap)
{ {
if (!ValidateCapabilityEnum(cap)) if (!ValidateCapabilityEnum(cap, "disable"))
return ErrorInvalidEnum("Disable: invalid capability enum"); return NS_OK;
MakeContextCurrent(); MakeContextCurrent();
gl->fDisable(cap); gl->fDisable(cap);
@ -1131,8 +1129,8 @@ WebGLContext::GetActiveAttrib(nsIWebGLProgram *pobj, PRUint32 index, nsIWebGLAct
NS_IMETHODIMP NS_IMETHODIMP
WebGLContext::GenerateMipmap(WebGLenum target) WebGLContext::GenerateMipmap(WebGLenum target)
{ {
if (!ValidateTextureTargetEnum(target)) if (!ValidateTextureTargetEnum(target, "generateMipmap"))
return ErrorInvalidEnum("GenerateMipmap: invalid target"); return NS_OK;
MakeContextCurrent(); MakeContextCurrent();
gl->fGenerateMipmap(target); gl->fGenerateMipmap(target);
@ -1855,8 +1853,8 @@ WebGLContext::GetTexParameter(WebGLenum target, WebGLenum pname, nsIVariant **re
MakeContextCurrent(); MakeContextCurrent();
if (!ValidateTextureTargetEnum(target)) if (!ValidateTextureTargetEnum(target, "getTexParameter: target"))
return ErrorInvalidEnum("GetTexParameter: invalid target"); return NS_OK;
switch (pname) { switch (pname) {
case LOCAL_GL_TEXTURE_MIN_FILTER: case LOCAL_GL_TEXTURE_MIN_FILTER:
@ -1871,7 +1869,7 @@ WebGLContext::GetTexParameter(WebGLenum target, WebGLenum pname, nsIVariant **re
break; break;
default: default:
return ErrorInvalidEnum("GetTexParameter: invalid parameter"); return ErrorInvalidEnum("getTexParameter: invalid parameter");
} }
*retval = wrval.forget().get(); *retval = wrval.forget().get();
@ -2109,9 +2107,9 @@ WebGLContext::IsTexture(nsIWebGLTexture *tobj, WebGLboolean *retval)
NS_IMETHODIMP NS_IMETHODIMP
WebGLContext::IsEnabled(WebGLenum cap, WebGLboolean *retval) WebGLContext::IsEnabled(WebGLenum cap, WebGLboolean *retval)
{ {
if (!ValidateCapabilityEnum(cap)) { if (!ValidateCapabilityEnum(cap, "isEnabled")) {
*retval = 0; // as per the OpenGL ES spec *retval = 0; // as per the OpenGL ES spec
return ErrorInvalidEnum("IsEnabled: invalid capability enum"); return NS_OK;
} }
MakeContextCurrent(); MakeContextCurrent();
@ -2413,8 +2411,8 @@ WebGLContext::Scissor(WebGLint x, WebGLint y, WebGLsizei width, WebGLsizei heigh
NS_IMETHODIMP NS_IMETHODIMP
WebGLContext::StencilFunc(WebGLenum func, WebGLint ref, WebGLuint mask) WebGLContext::StencilFunc(WebGLenum func, WebGLint ref, WebGLuint mask)
{ {
if (!ValidateComparisonEnum(func)) if (!ValidateComparisonEnum(func, "stencilFunc: func"))
return ErrorInvalidEnum("StencilFunc: invalid function enum"); return NS_OK;
MakeContextCurrent(); MakeContextCurrent();
gl->fStencilFunc(func, ref, mask); gl->fStencilFunc(func, ref, mask);
@ -2424,10 +2422,9 @@ WebGLContext::StencilFunc(WebGLenum func, WebGLint ref, WebGLuint mask)
NS_IMETHODIMP NS_IMETHODIMP
WebGLContext::StencilFuncSeparate(WebGLenum face, WebGLenum func, WebGLint ref, WebGLuint mask) WebGLContext::StencilFuncSeparate(WebGLenum face, WebGLenum func, WebGLint ref, WebGLuint mask)
{ {
if (!ValidateFaceEnum(face)) if (!ValidateFaceEnum(face, "stencilFuncSeparate: face") ||
return ErrorInvalidEnum("StencilFuncSeparate: invalid face enum"); !ValidateComparisonEnum(func, "stencilFuncSeparate: func"))
if (!ValidateComparisonEnum(func)) return NS_OK;
return ErrorInvalidEnum("StencilFuncSeparate: invalid function enum");
MakeContextCurrent(); MakeContextCurrent();
gl->fStencilFuncSeparate(face, func, ref, mask); gl->fStencilFuncSeparate(face, func, ref, mask);
@ -2439,8 +2436,8 @@ GL_SAME_METHOD_1(StencilMask, StencilMask, WebGLuint)
NS_IMETHODIMP NS_IMETHODIMP
WebGLContext::StencilMaskSeparate(WebGLenum face, WebGLuint mask) WebGLContext::StencilMaskSeparate(WebGLenum face, WebGLuint mask)
{ {
if (!ValidateFaceEnum(face)) if (!ValidateFaceEnum(face, "stencilMaskSeparate: face"))
return ErrorInvalidEnum("StencilFuncSeparate: invalid face enum"); return NS_OK;
MakeContextCurrent(); MakeContextCurrent();
gl->fStencilMaskSeparate(face, mask); gl->fStencilMaskSeparate(face, mask);
@ -2450,10 +2447,10 @@ WebGLContext::StencilMaskSeparate(WebGLenum face, WebGLuint mask)
NS_IMETHODIMP NS_IMETHODIMP
WebGLContext::StencilOp(WebGLenum sfail, WebGLenum dpfail, WebGLenum dppass) WebGLContext::StencilOp(WebGLenum sfail, WebGLenum dpfail, WebGLenum dppass)
{ {
if (!ValidateStencilOpEnum(sfail) || if (!ValidateStencilOpEnum(sfail, "stencilOp: sfail") ||
!ValidateStencilOpEnum(dpfail) || !ValidateStencilOpEnum(dpfail, "stencilOp: dpfail") ||
!ValidateStencilOpEnum(dppass)) !ValidateStencilOpEnum(dppass, "stencilOp: dppass"))
return ErrorInvalidEnum("StencilOp: invalid action enum"); return NS_OK;
MakeContextCurrent(); MakeContextCurrent();
gl->fStencilOp(sfail, dpfail, dppass); gl->fStencilOp(sfail, dpfail, dppass);
@ -2463,13 +2460,11 @@ WebGLContext::StencilOp(WebGLenum sfail, WebGLenum dpfail, WebGLenum dppass)
NS_IMETHODIMP NS_IMETHODIMP
WebGLContext::StencilOpSeparate(WebGLenum face, WebGLenum sfail, WebGLenum dpfail, WebGLenum dppass) WebGLContext::StencilOpSeparate(WebGLenum face, WebGLenum sfail, WebGLenum dpfail, WebGLenum dppass)
{ {
if (!ValidateFaceEnum(face)) if (!ValidateFaceEnum(face, "stencilOpSeparate: face") ||
return ErrorInvalidEnum("StencilOpSeparate: invalid face enum"); !ValidateStencilOpEnum(sfail, "stencilOpSeparate: sfail") ||
!ValidateStencilOpEnum(dpfail, "stencilOpSeparate: dpfail") ||
if (!ValidateStencilOpEnum(sfail) || !ValidateStencilOpEnum(dppass, "stencilOpSeparate: dppass"))
!ValidateStencilOpEnum(dpfail) || return NS_OK;
!ValidateStencilOpEnum(dppass))
return ErrorInvalidEnum("StencilOpSeparate: invalid action enum");
MakeContextCurrent(); MakeContextCurrent();
gl->fStencilOpSeparate(face, sfail, dpfail, dppass); gl->fStencilOpSeparate(face, sfail, dpfail, dppass);
@ -3013,7 +3008,7 @@ WebGLContext::TexImage2D_base(WebGLenum target, WebGLint level, WebGLenum intern
case LOCAL_GL_LUMINANCE_ALPHA: case LOCAL_GL_LUMINANCE_ALPHA:
break; break;
default: default:
return ErrorInvalidValue("TexImage2D: internal format not supported"); return ErrorInvalidEnum("TexImage2D: invalid internal format");
} }
if (width < 0 || height < 0) if (width < 0 || height < 0)
@ -3022,53 +3017,12 @@ WebGLContext::TexImage2D_base(WebGLenum target, WebGLint level, WebGLenum intern
if (border != 0) if (border != 0)
return ErrorInvalidValue("TexImage2D: border must be 0"); return ErrorInvalidValue("TexImage2D: border must be 0");
// number of bytes per pixel PRUint32 texelSize = 0;
uint32 bufferPixelSize = 0; if (!ValidateTexFormatAndType(format, type, &texelSize, "texImage2D"))
switch (format) { return NS_OK;
case LOCAL_GL_RED:
case LOCAL_GL_GREEN:
case LOCAL_GL_BLUE:
case LOCAL_GL_ALPHA:
case LOCAL_GL_LUMINANCE:
bufferPixelSize = 1;
break;
case LOCAL_GL_LUMINANCE_ALPHA:
bufferPixelSize = 2;
break;
case LOCAL_GL_RGB:
bufferPixelSize = 3;
break;
case LOCAL_GL_RGBA:
bufferPixelSize = 4;
break;
default:
return ErrorInvalidEnum("TexImage2D: pixel format not supported");
}
switch (type) {
case LOCAL_GL_BYTE:
case LOCAL_GL_UNSIGNED_BYTE:
break;
case LOCAL_GL_SHORT:
case LOCAL_GL_UNSIGNED_SHORT:
bufferPixelSize *= 2;
break;
case LOCAL_GL_INT:
case LOCAL_GL_UNSIGNED_INT:
case LOCAL_GL_FLOAT:
bufferPixelSize *= 4;
break;
case LOCAL_GL_UNSIGNED_SHORT_4_4_4_4:
case LOCAL_GL_UNSIGNED_SHORT_5_5_5_1:
case LOCAL_GL_UNSIGNED_SHORT_5_6_5:
bufferPixelSize *= 2;
break;
default:
return ErrorInvalidEnum("TexImage2D: invalid type argument");
}
// XXX overflow! // XXX overflow!
uint32 bytesNeeded = width * height * bufferPixelSize; uint32 bytesNeeded = width * height * texelSize;
if (byteLength && byteLength < bytesNeeded) if (byteLength && byteLength < bytesNeeded)
return ErrorInvalidValue("TexImage2D: not enough data for operation (need %d, have %d)", return ErrorInvalidValue("TexImage2D: not enough data for operation (need %d, have %d)",
@ -3193,56 +3147,15 @@ WebGLContext::TexSubImage2D_base(WebGLenum target, WebGLint level,
if (width < 0 || height < 0) if (width < 0 || height < 0)
return ErrorInvalidValue("TexSubImage2D: width and height must be > 0!"); return ErrorInvalidValue("TexSubImage2D: width and height must be > 0!");
PRUint32 texelSize = 0;
if (!ValidateTexFormatAndType(format, type, &texelSize, "texSubImage2D"))
return NS_OK;
if (width == 0 || height == 0) if (width == 0 || height == 0)
return NS_OK; // ES 2.0 says it has no effect, we better return right now return NS_OK; // ES 2.0 says it has no effect, we better return right now
// number of bytes per pixel
uint32 bufferPixelSize = 0;
switch (format) {
case LOCAL_GL_RED:
case LOCAL_GL_GREEN:
case LOCAL_GL_BLUE:
case LOCAL_GL_ALPHA:
case LOCAL_GL_LUMINANCE:
bufferPixelSize = 1;
break;
case LOCAL_GL_LUMINANCE_ALPHA:
bufferPixelSize = 2;
break;
case LOCAL_GL_RGB:
bufferPixelSize = 3;
break;
case LOCAL_GL_RGBA:
bufferPixelSize = 4;
break;
default:
return ErrorInvalidEnum("TexImage2D: pixel format not supported");
}
switch (type) {
case LOCAL_GL_BYTE:
case LOCAL_GL_UNSIGNED_BYTE:
break;
case LOCAL_GL_SHORT:
case LOCAL_GL_UNSIGNED_SHORT:
bufferPixelSize *= 2;
break;
case LOCAL_GL_INT:
case LOCAL_GL_UNSIGNED_INT:
case LOCAL_GL_FLOAT:
bufferPixelSize *= 4;
break;
case LOCAL_GL_UNSIGNED_SHORT_4_4_4_4:
case LOCAL_GL_UNSIGNED_SHORT_5_5_5_1:
case LOCAL_GL_UNSIGNED_SHORT_5_6_5:
bufferPixelSize *= 2;
break;
default:
return ErrorInvalidEnum("TexImage2D: invalid type argument");
}
// XXX overflow! // XXX overflow!
uint32 bytesNeeded = width * height * bufferPixelSize; uint32 bytesNeeded = width * height * texelSize;
if (byteLength < bytesNeeded) if (byteLength < bytesNeeded)
return ErrorInvalidValue("TexSubImage2D: not enough data for operation (need %d, have %d)", bytesNeeded, byteLength); return ErrorInvalidValue("TexSubImage2D: not enough data for operation (need %d, have %d)", bytesNeeded, byteLength);

View File

@ -125,7 +125,7 @@ WebGLContext::ValidateBuffers(PRUint32 count)
return PR_TRUE; return PR_TRUE;
} }
PRBool WebGLContext::ValidateCapabilityEnum(WebGLenum cap) PRBool WebGLContext::ValidateCapabilityEnum(WebGLenum cap, const char *info)
{ {
switch (cap) { switch (cap) {
case LOCAL_GL_BLEND: case LOCAL_GL_BLEND:
@ -139,11 +139,12 @@ PRBool WebGLContext::ValidateCapabilityEnum(WebGLenum cap)
case LOCAL_GL_STENCIL_TEST: case LOCAL_GL_STENCIL_TEST:
return PR_TRUE; return PR_TRUE;
default: default:
ErrorInvalidEnumInfo(info);
return PR_FALSE; return PR_FALSE;
} }
} }
PRBool WebGLContext::ValidateBlendEquationEnum(WebGLenum mode) PRBool WebGLContext::ValidateBlendEquationEnum(WebGLenum mode, const char *info)
{ {
switch (mode) { switch (mode) {
case LOCAL_GL_FUNC_ADD: case LOCAL_GL_FUNC_ADD:
@ -151,11 +152,12 @@ PRBool WebGLContext::ValidateBlendEquationEnum(WebGLenum mode)
case LOCAL_GL_FUNC_REVERSE_SUBTRACT: case LOCAL_GL_FUNC_REVERSE_SUBTRACT:
return PR_TRUE; return PR_TRUE;
default: default:
ErrorInvalidEnumInfo(info);
return PR_FALSE; return PR_FALSE;
} }
} }
PRBool WebGLContext::ValidateBlendFuncDstEnum(WebGLenum factor) PRBool WebGLContext::ValidateBlendFuncDstEnum(WebGLenum factor, const char *info)
{ {
switch (factor) { switch (factor) {
case LOCAL_GL_ZERO: case LOCAL_GL_ZERO:
@ -174,30 +176,32 @@ PRBool WebGLContext::ValidateBlendFuncDstEnum(WebGLenum factor)
case LOCAL_GL_ONE_MINUS_CONSTANT_ALPHA: case LOCAL_GL_ONE_MINUS_CONSTANT_ALPHA:
return PR_TRUE; return PR_TRUE;
default: default:
ErrorInvalidEnumInfo(info);
return PR_FALSE; return PR_FALSE;
} }
} }
PRBool WebGLContext::ValidateBlendFuncSrcEnum(WebGLenum factor) PRBool WebGLContext::ValidateBlendFuncSrcEnum(WebGLenum factor, const char *info)
{ {
if(factor == LOCAL_GL_SRC_ALPHA_SATURATE) if (factor == LOCAL_GL_SRC_ALPHA_SATURATE)
return PR_TRUE; return PR_TRUE;
else else
return ValidateBlendFuncDstEnum(factor); return ValidateBlendFuncDstEnum(factor, info);
} }
PRBool WebGLContext::ValidateTextureTargetEnum(WebGLenum target) PRBool WebGLContext::ValidateTextureTargetEnum(WebGLenum target, const char *info)
{ {
switch (target) { switch (target) {
case LOCAL_GL_TEXTURE_2D: case LOCAL_GL_TEXTURE_2D:
case LOCAL_GL_TEXTURE_CUBE_MAP: case LOCAL_GL_TEXTURE_CUBE_MAP:
return PR_TRUE; return PR_TRUE;
default: default:
ErrorInvalidEnumInfo(info);
return PR_FALSE; return PR_FALSE;
} }
} }
PRBool WebGLContext::ValidateComparisonEnum(WebGLenum target) PRBool WebGLContext::ValidateComparisonEnum(WebGLenum target, const char *info)
{ {
switch (target) { switch (target) {
case LOCAL_GL_NEVER: case LOCAL_GL_NEVER:
@ -210,11 +214,12 @@ PRBool WebGLContext::ValidateComparisonEnum(WebGLenum target)
case LOCAL_GL_ALWAYS: case LOCAL_GL_ALWAYS:
return PR_TRUE; return PR_TRUE;
default: default:
ErrorInvalidEnumInfo(info);
return PR_FALSE; return PR_FALSE;
} }
} }
PRBool WebGLContext::ValidateStencilOpEnum(WebGLenum action) PRBool WebGLContext::ValidateStencilOpEnum(WebGLenum action, const char *info)
{ {
switch (action) { switch (action) {
case LOCAL_GL_KEEP: case LOCAL_GL_KEEP:
@ -227,11 +232,12 @@ PRBool WebGLContext::ValidateStencilOpEnum(WebGLenum action)
case LOCAL_GL_INVERT: case LOCAL_GL_INVERT:
return PR_TRUE; return PR_TRUE;
default: default:
ErrorInvalidEnumInfo(info);
return PR_FALSE; return PR_FALSE;
} }
} }
PRBool WebGLContext::ValidateFaceEnum(WebGLenum target) PRBool WebGLContext::ValidateFaceEnum(WebGLenum target, const char *info)
{ {
switch (target) { switch (target) {
case LOCAL_GL_FRONT: case LOCAL_GL_FRONT:
@ -239,10 +245,63 @@ PRBool WebGLContext::ValidateFaceEnum(WebGLenum target)
case LOCAL_GL_FRONT_AND_BACK: case LOCAL_GL_FRONT_AND_BACK:
return PR_TRUE; return PR_TRUE;
default: default:
ErrorInvalidEnumInfo(info);
return PR_FALSE; return PR_FALSE;
} }
} }
PRBool WebGLContext::ValidateTexFormatAndType(WebGLenum format, WebGLenum type,
PRUint32 *texelSize, const char *info)
{
if (type == LOCAL_GL_UNSIGNED_BYTE)
{
switch (format) {
case LOCAL_GL_RED:
case LOCAL_GL_GREEN:
case LOCAL_GL_BLUE:
case LOCAL_GL_ALPHA:
case LOCAL_GL_LUMINANCE:
*texelSize = 1;
return PR_TRUE;
case LOCAL_GL_LUMINANCE_ALPHA:
*texelSize = 2;
return PR_TRUE;
case LOCAL_GL_RGB:
*texelSize = 3;
return PR_TRUE;
case LOCAL_GL_RGBA:
*texelSize = 4;
return PR_TRUE;
default:
ErrorInvalidEnum("%s: invalid format", info);
return PR_FALSE;
}
} else {
switch (type) {
case LOCAL_GL_UNSIGNED_SHORT_4_4_4_4:
case LOCAL_GL_UNSIGNED_SHORT_5_5_5_1:
if (format == LOCAL_GL_RGBA) {
*texelSize = 2;
return PR_TRUE;
} else {
ErrorInvalidOperation("%s: mutually incompatible format and type", info);
return PR_FALSE;
}
case LOCAL_GL_UNSIGNED_SHORT_5_6_5:
if (format == LOCAL_GL_RGB) {
*texelSize = 2;
return PR_TRUE;
} else {
ErrorInvalidOperation("%s: mutually incompatible format and type", info);
return PR_FALSE;
}
default:
ErrorInvalidEnum("%s: invalid type", info);
return PR_FALSE;
}
}
}
PRBool PRBool
WebGLContext::InitAndValidateGL() WebGLContext::InitAndValidateGL()
{ {