Bug 636942 - stencil separate param validation must now occur on draw calls - r=jrmuizel

We were validating these params when they're set, and that was non-conformant behavior.
This commit is contained in:
Benoit Jacob 2011-05-20 15:53:53 -04:00
parent a392b3f339
commit 3b22833d8a
7 changed files with 71 additions and 22 deletions

View File

@ -140,9 +140,13 @@ WebGLContext::WebGLContext()
mColorClearValue[3] = 0.f;
mDepthClearValue = 1.f;
mStencilClearValue = 0;
mStencilRef = 0;
mStencilValueMask = 0xffffffff;
mStencilWriteMask = 0xffffffff;
mStencilRefFront = 0;
mStencilRefBack = 0;
mStencilValueMaskFront = 0xffffffff;
mStencilValueMaskBack = 0xffffffff;
mStencilWriteMaskFront = 0xffffffff;
mStencilWriteMaskBack = 0xffffffff;
mScissorTestEnabled = 0;
mDitherEnabled = 1;
mBackbufferClearingStatus = BackbufferClearingStatus::NotClearedSinceLastPresented;
@ -860,7 +864,8 @@ WebGLContext::ForceClearFramebufferWithDefaultValues(PRUint32 mask, const nsIntR
}
if (initializeStencilBuffer) {
gl->fStencilMask(mStencilWriteMask);
gl->fStencilMaskSeparate(LOCAL_GL_FRONT, mStencilWriteMaskFront);
gl->fStencilMaskSeparate(LOCAL_GL_BACK, mStencilWriteMaskBack);
gl->fClearStencil(mStencilClearValue);
}

View File

@ -465,6 +465,7 @@ protected:
PRUint32 *texelSize, const char *info);
PRBool ValidateDrawModeEnum(WebGLenum mode, const char *info);
PRBool ValidateAttribIndex(WebGLuint index, const char *info);
PRBool ValidateStencilParamsForDrawCall();
void Invalidate();
void DestroyResourcesAndContext();
@ -591,8 +592,9 @@ protected:
GLuint mFakeVertexAttrib0BufferObject;
int mFakeVertexAttrib0BufferStatus;
WebGLint mStencilRef;
WebGLuint mStencilValueMask, mStencilWriteMask;
WebGLint mStencilRefFront, mStencilRefBack;
WebGLuint mStencilValueMaskFront, mStencilValueMaskBack,
mStencilWriteMaskFront, mStencilWriteMaskBack;
realGLboolean mColorWriteMask[4];
realGLboolean mDepthWriteMask;
realGLboolean mScissorTestEnabled;

View File

@ -1363,6 +1363,9 @@ WebGLContext::DrawArrays(GLenum mode, WebGLint first, WebGLsizei count)
if (first < 0 || count < 0)
return ErrorInvalidValue("DrawArrays: negative first or count");
if (!ValidateStencilParamsForDrawCall())
return NS_OK;
// If count is 0, there's nothing to do.
if (count == 0)
return NS_OK;
@ -1416,6 +1419,9 @@ WebGLContext::DrawElements(WebGLenum mode, WebGLsizei count, WebGLenum type, Web
if (count < 0 || byteOffset < 0)
return ErrorInvalidValue("DrawElements: negative count or offset");
if (!ValidateStencilParamsForDrawCall())
return NS_OK;
// If count is 0, there's nothing to do.
if (count == 0)
return NS_OK;
@ -3166,8 +3172,10 @@ WebGLContext::StencilFunc(WebGLenum func, WebGLint ref, WebGLuint mask)
if (!ValidateComparisonEnum(func, "stencilFunc: func"))
return NS_OK;
mStencilRef = ref;
mStencilValueMask = mask;
mStencilRefFront = ref;
mStencilRefBack = ref;
mStencilValueMaskFront = mask;
mStencilValueMaskBack = mask;
MakeContextCurrent();
gl->fStencilFunc(func, ref, mask);
@ -3181,12 +3189,22 @@ WebGLContext::StencilFuncSeparate(WebGLenum face, WebGLenum func, WebGLint ref,
!ValidateComparisonEnum(func, "stencilFuncSeparate: func"))
return NS_OK;
if (face != LOCAL_GL_FRONT_AND_BACK && (ref != mStencilRef || mask != mStencilValueMask))
return ErrorInvalidOperation("stencilFuncSeparate: WebGL doesn't currently allow specifying "
"different values for front and back.");
mStencilRef = ref;
mStencilValueMask = mask;
switch (face) {
case LOCAL_GL_FRONT_AND_BACK:
mStencilRefFront = ref;
mStencilRefBack = ref;
mStencilValueMaskFront = mask;
mStencilValueMaskBack = mask;
break;
case LOCAL_GL_FRONT:
mStencilRefFront = ref;
mStencilValueMaskFront = mask;
break;
case LOCAL_GL_BACK:
mStencilRefBack = ref;
mStencilValueMaskBack = mask;
break;
}
MakeContextCurrent();
gl->fStencilFuncSeparate(face, func, ref, mask);
@ -3196,7 +3214,8 @@ WebGLContext::StencilFuncSeparate(WebGLenum face, WebGLenum func, WebGLint ref,
NS_IMETHODIMP
WebGLContext::StencilMask(WebGLuint mask)
{
mStencilWriteMask = mask;
mStencilWriteMaskFront = mask;
mStencilWriteMaskBack = mask;
MakeContextCurrent();
gl->fStencilMask(mask);
@ -3209,10 +3228,18 @@ WebGLContext::StencilMaskSeparate(WebGLenum face, WebGLuint mask)
if (!ValidateFaceEnum(face, "stencilMaskSeparate: face"))
return NS_OK;
if (face != LOCAL_GL_FRONT_AND_BACK && mask != mStencilWriteMask)
return ErrorInvalidOperation("stencilMaskSeparate: WebGL doesn't currently allow specifying "
"different values for front and back.");
mStencilWriteMask = mask;
switch (face) {
case LOCAL_GL_FRONT_AND_BACK:
mStencilWriteMaskFront = mask;
mStencilWriteMaskBack = mask;
break;
case LOCAL_GL_FRONT:
mStencilWriteMaskFront = mask;
break;
case LOCAL_GL_BACK:
mStencilWriteMaskBack = mask;
break;
}
MakeContextCurrent();
gl->fStencilMaskSeparate(face, mask);

View File

@ -419,6 +419,24 @@ PRBool WebGLContext::ValidateAttribIndex(WebGLuint index, const char *info)
}
}
PRBool WebGLContext::ValidateStencilParamsForDrawCall()
{
const char *msg = "%s set different front and back stencil %s. Drawing in this configuration is not allowed.";
if (mStencilRefFront != mStencilRefBack) {
ErrorInvalidOperation(msg, "stencilFuncSeparate", "reference values");
return PR_FALSE;
}
if (mStencilValueMaskFront != mStencilValueMaskBack) {
ErrorInvalidOperation(msg, "stencilFuncSeparate", "value masks");
return PR_FALSE;
}
if (mStencilWriteMaskFront != mStencilWriteMaskBack) {
ErrorInvalidOperation(msg, "stencilMaskSeparate", "write masks");
return PR_FALSE;
}
return PR_TRUE;
}
PRBool
WebGLContext::InitAndValidateGL()
{

View File

@ -17,4 +17,3 @@ conformance/object-deletion-behaviour.html
conformance/read-pixels-test.html
conformance/tex-sub-image-2d-bad-args.html
conformance/uninitialized-test.html
conformance/webgl-specific.html

View File

@ -9,7 +9,6 @@ conformance/read-pixels-test.html
conformance/tex-input-validation.html
conformance/tex-sub-image-2d-bad-args.html
conformance/uninitialized-test.html
conformance/webgl-specific.html
conformance/more/functions/copyTexImage2D.html
conformance/more/functions/copyTexSubImage2D.html
conformance/more/functions/copyTexSubImage2DBadArgs.html

View File

@ -5,7 +5,6 @@ conformance/object-deletion-behaviour.html
conformance/read-pixels-test.html
conformance/tex-sub-image-2d-bad-args.html
conformance/uninitialized-test.html
conformance/webgl-specific.html
conformance/more/conformance/quickCheckAPI.html
conformance/more/functions/copyTexImage2D.html
conformance/more/functions/copyTexSubImage2D.html