зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1004309 - Add func to assert shadowed state is correct. - r=kamidphish
* * * Bug 980178 - Dither default is true. - r=kamidphish
This commit is contained in:
Родитель
5d9a310465
Коммит
a459231c85
|
@ -588,14 +588,12 @@ WebGLContext::SetDimensions(int32_t width, int32_t height)
|
|||
// we'll end up displaying random memory
|
||||
gl->fBindFramebuffer(LOCAL_GL_FRAMEBUFFER, 0);
|
||||
|
||||
gl->fClearColor(0.0f, 0.0f, 0.0f, 0.0f);
|
||||
gl->fClearDepth(1.0f);
|
||||
gl->fClearStencil(0);
|
||||
|
||||
mBackbufferNeedsClear = true;
|
||||
AssertCachedBindings();
|
||||
AssertCachedState();
|
||||
|
||||
// Clear immediately, because we need to present the cleared initial
|
||||
// buffer.
|
||||
mBackbufferNeedsClear = true;
|
||||
ClearBackbufferIfNeeded();
|
||||
|
||||
mShouldPresent = true;
|
||||
|
@ -607,6 +605,9 @@ WebGLContext::SetDimensions(int32_t width, int32_t height)
|
|||
MOZ_ASSERT(gl->Caps().antialias == caps.antialias || !gl->Caps().antialias);
|
||||
MOZ_ASSERT(gl->Caps().preserve == caps.preserve);
|
||||
|
||||
AssertCachedBindings();
|
||||
AssertCachedState();
|
||||
|
||||
reporter.SetSuccessful();
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -973,19 +974,6 @@ WebGLContext::ClearScreen()
|
|||
ForceClearFramebufferWithDefaultValues(clearMask, colorAttachmentsMask);
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
// For NaNs, etc.
|
||||
static bool IsShadowCorrect(float shadow, float actual) {
|
||||
if (IsNaN(shadow)) {
|
||||
// GL is allowed to do anything it wants for NaNs, so if we're shadowing
|
||||
// a NaN, then whatever `actual` is might be correct.
|
||||
return true;
|
||||
}
|
||||
|
||||
return shadow == actual;
|
||||
}
|
||||
#endif
|
||||
|
||||
void
|
||||
WebGLContext::ForceClearFramebufferWithDefaultValues(GLbitfield mask, const bool colorAttachmentsMask[kMaxColorAttachments])
|
||||
{
|
||||
|
@ -1000,67 +988,8 @@ WebGLContext::ForceClearFramebufferWithDefaultValues(GLbitfield mask, const bool
|
|||
|
||||
// Fun GL fact: No need to worry about the viewport here, glViewport is just
|
||||
// setting up a coordinates transformation, it doesn't affect glClear at all.
|
||||
|
||||
#ifdef DEBUG
|
||||
// Scope to hide our variables.
|
||||
{
|
||||
// Sanity-check that all our state is set properly. Otherwise, when we
|
||||
// reset out state to what we *think* it is, we'll get it wrong.
|
||||
|
||||
// Dither shouldn't matter when we're clearing to {0,0,0,0}.
|
||||
MOZ_ASSERT(gl->fIsEnabled(LOCAL_GL_SCISSOR_TEST) == mScissorTestEnabled);
|
||||
|
||||
if (initializeColorBuffer) {
|
||||
realGLboolean colorWriteMask[4] = {2, 2, 2, 2};
|
||||
GLfloat colorClearValue[4] = {-1.0f, -1.0f, -1.0f, -1.0f};
|
||||
|
||||
gl->fGetBooleanv(LOCAL_GL_COLOR_WRITEMASK, colorWriteMask);
|
||||
gl->fGetFloatv(LOCAL_GL_COLOR_CLEAR_VALUE, colorClearValue);
|
||||
|
||||
MOZ_ASSERT(colorWriteMask[0] == mColorWriteMask[0] &&
|
||||
colorWriteMask[1] == mColorWriteMask[1] &&
|
||||
colorWriteMask[2] == mColorWriteMask[2] &&
|
||||
colorWriteMask[3] == mColorWriteMask[3]);
|
||||
MOZ_ASSERT(IsShadowCorrect(mColorClearValue[0], colorClearValue[0]) &&
|
||||
IsShadowCorrect(mColorClearValue[1], colorClearValue[1]) &&
|
||||
IsShadowCorrect(mColorClearValue[2], colorClearValue[2]) &&
|
||||
IsShadowCorrect(mColorClearValue[3], colorClearValue[3]));
|
||||
}
|
||||
|
||||
if (initializeDepthBuffer) {
|
||||
realGLboolean depthWriteMask = 2;
|
||||
GLfloat depthClearValue = -1.0f;
|
||||
|
||||
|
||||
gl->fGetBooleanv(LOCAL_GL_DEPTH_WRITEMASK, &depthWriteMask);
|
||||
gl->fGetFloatv(LOCAL_GL_DEPTH_CLEAR_VALUE, &depthClearValue);
|
||||
|
||||
MOZ_ASSERT(depthWriteMask == mDepthWriteMask);
|
||||
MOZ_ASSERT(IsShadowCorrect(mDepthClearValue, depthClearValue));
|
||||
}
|
||||
|
||||
if (initializeStencilBuffer) {
|
||||
GLuint stencilWriteMaskFront = 0xdeadbad1;
|
||||
GLuint stencilWriteMaskBack = 0xdeadbad1;
|
||||
GLuint stencilClearValue = 0xdeadbad1;
|
||||
|
||||
gl->GetUIntegerv(LOCAL_GL_STENCIL_WRITEMASK, &stencilWriteMaskFront);
|
||||
gl->GetUIntegerv(LOCAL_GL_STENCIL_BACK_WRITEMASK, &stencilWriteMaskBack);
|
||||
gl->GetUIntegerv(LOCAL_GL_STENCIL_CLEAR_VALUE, &stencilClearValue);
|
||||
|
||||
GLuint stencilBits = 0;
|
||||
gl->GetUIntegerv(LOCAL_GL_STENCIL_BITS, &stencilBits);
|
||||
GLuint stencilMask = (GLuint(1) << stencilBits) - 1;
|
||||
|
||||
MOZ_ASSERT( ( stencilWriteMaskFront & stencilMask) ==
|
||||
(mStencilWriteMaskFront & stencilMask) );
|
||||
MOZ_ASSERT( ( stencilWriteMaskBack & stencilMask) ==
|
||||
(mStencilWriteMaskBack & stencilMask) );
|
||||
MOZ_ASSERT( ( stencilClearValue & stencilMask) ==
|
||||
(mStencilClearValue & stencilMask) );
|
||||
}
|
||||
}
|
||||
#endif
|
||||
AssertCachedState(); // Can't check cached bindings, as we could
|
||||
// have a different FB bound temporarily.
|
||||
|
||||
// Prepare GL state for clearing.
|
||||
gl->fDisable(LOCAL_GL_SCISSOR_TEST);
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
#include "GLDefs.h"
|
||||
#include "WebGLActiveInfo.h"
|
||||
#include "WebGLObjectModel.h"
|
||||
#include "WebGLRenderbuffer.h"
|
||||
#include <stdarg.h>
|
||||
|
||||
#include "nsTArray.h"
|
||||
|
@ -88,6 +89,8 @@ class SourceSurface;
|
|||
|
||||
WebGLTexelFormat GetWebGLTexelFormat(GLenum format, GLenum type);
|
||||
|
||||
void AssertUintParamCorrect(gl::GLContext* gl, GLenum pname, GLuint shadow);
|
||||
|
||||
struct WebGLContextOptions {
|
||||
// these are defaults
|
||||
WebGLContextOptions();
|
||||
|
@ -114,6 +117,19 @@ struct WebGLContextOptions {
|
|||
bool preserveDrawingBuffer;
|
||||
};
|
||||
|
||||
#ifdef DEBUG
|
||||
static bool
|
||||
IsTextureBinding(GLenum binding)
|
||||
{
|
||||
switch (binding) {
|
||||
case LOCAL_GL_TEXTURE_BINDING_2D:
|
||||
case LOCAL_GL_TEXTURE_BINDING_CUBE_MAP:
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
class WebGLContext :
|
||||
public nsIDOMWebGLRenderingContext,
|
||||
public nsICanvasRenderingContextInternal,
|
||||
|
@ -204,7 +220,8 @@ public:
|
|||
|
||||
void DummyFramebufferOperation(const char *info);
|
||||
|
||||
WebGLTexture *activeBoundTextureForTarget(GLenum target) const {
|
||||
WebGLTexture* activeBoundTextureForTarget(GLenum target) const {
|
||||
MOZ_ASSERT(!IsTextureBinding(target));
|
||||
return target == LOCAL_GL_TEXTURE_2D ? mBound2DTextures[mActiveTexture]
|
||||
: mBoundCubeMapTextures[mActiveTexture];
|
||||
}
|
||||
|
@ -249,6 +266,9 @@ public:
|
|||
void SetupContextLossTimer();
|
||||
void TerminateContextLossTimer();
|
||||
|
||||
void AssertCachedBindings();
|
||||
void AssertCachedState();
|
||||
|
||||
// WebIDL WebGLRenderingContext API
|
||||
dom::HTMLCanvasElement* GetCanvas() const { return mCanvasElement; }
|
||||
GLsizei DrawingBufferWidth() const { return IsContextLost() ? 0 : mWidth; }
|
||||
|
|
|
@ -3,25 +3,26 @@
|
|||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "WebGLContext.h"
|
||||
|
||||
#include <stdarg.h>
|
||||
|
||||
#include "WebGLContext.h"
|
||||
#include "GLContext.h"
|
||||
|
||||
#include "prprf.h"
|
||||
|
||||
#include "jsapi.h"
|
||||
#include "nsIScriptSecurityManager.h"
|
||||
#include "nsServiceManagerUtils.h"
|
||||
#include "nsIVariant.h"
|
||||
#include "nsCxPusher.h"
|
||||
|
||||
#include "nsIDOMEvent.h"
|
||||
#include "nsIDOMDataContainerEvent.h"
|
||||
|
||||
#include "mozilla/Preferences.h"
|
||||
|
||||
using namespace mozilla;
|
||||
#include "nsCxPusher.h"
|
||||
#include "nsIDOMDataContainerEvent.h"
|
||||
#include "nsIDOMEvent.h"
|
||||
#include "nsIScriptSecurityManager.h"
|
||||
#include "nsIVariant.h"
|
||||
#include "nsServiceManagerUtils.h"
|
||||
#include "prprf.h"
|
||||
#include "WebGLBuffer.h"
|
||||
#include "WebGLExtensions.h"
|
||||
#include "WebGLFramebuffer.h"
|
||||
#include "WebGLProgram.h"
|
||||
#include "WebGLTexture.h"
|
||||
#include "WebGLVertexArray.h"
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
|
@ -193,8 +194,6 @@ DriverTypeFromType(GLContext* gl, GLenum webGLType)
|
|||
return webGLType;
|
||||
}
|
||||
|
||||
} // namespace mozilla
|
||||
|
||||
void
|
||||
WebGLContext::GenerateWarning(const char *fmt, ...)
|
||||
{
|
||||
|
@ -398,3 +397,151 @@ WebGLContext::GetAndFlushUnderlyingGLErrors()
|
|||
|
||||
return error;
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
// For NaNs, etc.
|
||||
static bool
|
||||
IsCacheCorrect(float cached, float actual)
|
||||
{
|
||||
if (IsNaN(cached)) {
|
||||
// GL is allowed to do anything it wants for NaNs, so if we're shadowing
|
||||
// a NaN, then whatever `actual` is might be correct.
|
||||
return true;
|
||||
}
|
||||
|
||||
return cached == actual;
|
||||
}
|
||||
|
||||
void
|
||||
AssertUintParamCorrect(gl::GLContext* gl, GLenum pname, GLuint shadow)
|
||||
{
|
||||
GLuint val = 0;
|
||||
gl->GetUIntegerv(pname, &val);
|
||||
if (val != shadow) {
|
||||
printf_stderr("Failed 0x%04x shadow: Cached 0x%x/%u, should be 0x%x/%u.\n",
|
||||
pname, shadow, shadow, val, val);
|
||||
MOZ_ASSERT(false, "Bad cached value.");
|
||||
}
|
||||
}
|
||||
#else
|
||||
void
|
||||
AssertUintParamCorrect(gl::GLContext*, GLenum, GLuint)
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
||||
void
|
||||
WebGLContext::AssertCachedBindings()
|
||||
{
|
||||
#ifdef DEBUG
|
||||
MakeContextCurrent();
|
||||
|
||||
GetAndFlushUnderlyingGLErrors();
|
||||
|
||||
if (IsExtensionEnabled(WebGLExtensionID::OES_vertex_array_object)) {
|
||||
GLuint bound = mBoundVertexArray ? mBoundVertexArray->GLName() : 0;
|
||||
AssertUintParamCorrect(gl, LOCAL_GL_VERTEX_ARRAY_BINDING, bound);
|
||||
}
|
||||
|
||||
// Bound object state
|
||||
GLuint bound = mBoundFramebuffer ? mBoundFramebuffer->GLName() : 0;
|
||||
AssertUintParamCorrect(gl, LOCAL_GL_FRAMEBUFFER_BINDING, bound);
|
||||
|
||||
bound = mCurrentProgram ? mCurrentProgram->GLName() : 0;
|
||||
AssertUintParamCorrect(gl, LOCAL_GL_CURRENT_PROGRAM, bound);
|
||||
|
||||
// Textures
|
||||
GLenum activeTexture = mActiveTexture + LOCAL_GL_TEXTURE0;
|
||||
AssertUintParamCorrect(gl, LOCAL_GL_ACTIVE_TEXTURE, activeTexture);
|
||||
|
||||
WebGLTexture* curTex = activeBoundTextureForTarget(LOCAL_GL_TEXTURE_2D);
|
||||
bound = curTex ? curTex->GLName() : 0;
|
||||
AssertUintParamCorrect(gl, LOCAL_GL_TEXTURE_BINDING_2D, bound);
|
||||
|
||||
curTex = activeBoundTextureForTarget(LOCAL_GL_TEXTURE_CUBE_MAP);
|
||||
bound = curTex ? curTex->GLName() : 0;
|
||||
AssertUintParamCorrect(gl, LOCAL_GL_TEXTURE_BINDING_CUBE_MAP, bound);
|
||||
|
||||
// Buffers
|
||||
bound = mBoundArrayBuffer ? mBoundArrayBuffer->GLName() : 0;
|
||||
AssertUintParamCorrect(gl, LOCAL_GL_ARRAY_BUFFER_BINDING, bound);
|
||||
|
||||
MOZ_ASSERT(mBoundVertexArray);
|
||||
WebGLBuffer* curBuff = mBoundVertexArray->mBoundElementArrayBuffer;
|
||||
bound = curBuff ? curBuff->GLName() : 0;
|
||||
AssertUintParamCorrect(gl, LOCAL_GL_ELEMENT_ARRAY_BUFFER_BINDING, bound);
|
||||
|
||||
MOZ_ASSERT(!GetAndFlushUnderlyingGLErrors());
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
WebGLContext::AssertCachedState()
|
||||
{
|
||||
#ifdef DEBUG
|
||||
MakeContextCurrent();
|
||||
|
||||
GetAndFlushUnderlyingGLErrors();
|
||||
|
||||
// extensions
|
||||
if (IsExtensionEnabled(WebGLExtensionID::WEBGL_draw_buffers)) {
|
||||
AssertUintParamCorrect(gl, LOCAL_GL_MAX_COLOR_ATTACHMENTS, mGLMaxColorAttachments);
|
||||
AssertUintParamCorrect(gl, LOCAL_GL_MAX_DRAW_BUFFERS, mGLMaxDrawBuffers);
|
||||
}
|
||||
|
||||
// Draw state
|
||||
MOZ_ASSERT(gl->fIsEnabled(LOCAL_GL_SCISSOR_TEST) == mScissorTestEnabled);
|
||||
MOZ_ASSERT(gl->fIsEnabled(LOCAL_GL_DITHER) == mDitherEnabled);
|
||||
MOZ_ASSERT_IF(IsWebGL2(),
|
||||
gl->fIsEnabled(LOCAL_GL_RASTERIZER_DISCARD) == mRasterizerDiscardEnabled);
|
||||
|
||||
|
||||
realGLboolean colorWriteMask[4] = {0, 0, 0, 0};
|
||||
gl->fGetBooleanv(LOCAL_GL_COLOR_WRITEMASK, colorWriteMask);
|
||||
MOZ_ASSERT(colorWriteMask[0] == mColorWriteMask[0] &&
|
||||
colorWriteMask[1] == mColorWriteMask[1] &&
|
||||
colorWriteMask[2] == mColorWriteMask[2] &&
|
||||
colorWriteMask[3] == mColorWriteMask[3]);
|
||||
|
||||
GLfloat colorClearValue[4] = {0.0f, 0.0f, 0.0f, 0.0f};
|
||||
gl->fGetFloatv(LOCAL_GL_COLOR_CLEAR_VALUE, colorClearValue);
|
||||
MOZ_ASSERT(IsCacheCorrect(mColorClearValue[0], colorClearValue[0]) &&
|
||||
IsCacheCorrect(mColorClearValue[1], colorClearValue[1]) &&
|
||||
IsCacheCorrect(mColorClearValue[2], colorClearValue[2]) &&
|
||||
IsCacheCorrect(mColorClearValue[3], colorClearValue[3]));
|
||||
|
||||
realGLboolean depthWriteMask = 0;
|
||||
gl->fGetBooleanv(LOCAL_GL_DEPTH_WRITEMASK, &depthWriteMask);
|
||||
MOZ_ASSERT(depthWriteMask == mDepthWriteMask);
|
||||
|
||||
GLfloat depthClearValue = 0.0f;
|
||||
gl->fGetFloatv(LOCAL_GL_DEPTH_CLEAR_VALUE, &depthClearValue);
|
||||
MOZ_ASSERT(IsCacheCorrect(mDepthClearValue, depthClearValue));
|
||||
|
||||
AssertUintParamCorrect(gl, LOCAL_GL_STENCIL_CLEAR_VALUE, mStencilClearValue);
|
||||
|
||||
AssertUintParamCorrect(gl, LOCAL_GL_STENCIL_REF, mStencilRefFront);
|
||||
AssertUintParamCorrect(gl, LOCAL_GL_STENCIL_BACK_REF, mStencilRefBack);
|
||||
|
||||
AssertUintParamCorrect(gl, LOCAL_GL_STENCIL_VALUE_MASK, mStencilValueMaskFront);
|
||||
AssertUintParamCorrect(gl, LOCAL_GL_STENCIL_BACK_VALUE_MASK, mStencilValueMaskBack);
|
||||
|
||||
AssertUintParamCorrect(gl, LOCAL_GL_STENCIL_WRITEMASK, mStencilWriteMaskFront);
|
||||
AssertUintParamCorrect(gl, LOCAL_GL_STENCIL_BACK_WRITEMASK, mStencilWriteMaskBack);
|
||||
|
||||
// Viewport
|
||||
GLint int4[4] = {0, 0, 0, 0};
|
||||
gl->fGetIntegerv(LOCAL_GL_VIEWPORT, int4);
|
||||
MOZ_ASSERT(int4[0] == mViewportX &&
|
||||
int4[1] == mViewportY &&
|
||||
int4[2] == mViewportWidth &&
|
||||
int4[3] == mViewportHeight);
|
||||
|
||||
AssertUintParamCorrect(gl, LOCAL_GL_PACK_ALIGNMENT, mPixelStorePackAlignment);
|
||||
AssertUintParamCorrect(gl, LOCAL_GL_UNPACK_ALIGNMENT, mPixelStoreUnpackAlignment);
|
||||
|
||||
MOZ_ASSERT(!GetAndFlushUnderlyingGLErrors());
|
||||
#endif
|
||||
}
|
||||
|
||||
} // namespace mozilla
|
||||
|
|
|
@ -1642,10 +1642,32 @@ WebGLContext::InitAndValidateGL()
|
|||
mStencilClearValue = 0;
|
||||
mStencilRefFront = 0;
|
||||
mStencilRefBack = 0;
|
||||
mStencilValueMaskFront = 0xffffffff;
|
||||
mStencilValueMaskBack = 0xffffffff;
|
||||
mStencilWriteMaskFront = 0xffffffff;
|
||||
mStencilWriteMaskBack = 0xffffffff;
|
||||
|
||||
/*
|
||||
// Technically, we should be setting mStencil[...] values to
|
||||
// `allOnes`, but either ANGLE breaks or the SGX540s on Try break.
|
||||
GLuint stencilBits = 0;
|
||||
gl->GetUIntegerv(LOCAL_GL_STENCIL_BITS, &stencilBits);
|
||||
GLuint allOnes = ~(UINT32_MAX << stencilBits);
|
||||
mStencilValueMaskFront = allOnes;
|
||||
mStencilValueMaskBack = allOnes;
|
||||
mStencilWriteMaskFront = allOnes;
|
||||
mStencilWriteMaskBack = allOnes;
|
||||
*/
|
||||
|
||||
gl->GetUIntegerv(LOCAL_GL_STENCIL_VALUE_MASK, &mStencilValueMaskFront);
|
||||
gl->GetUIntegerv(LOCAL_GL_STENCIL_BACK_VALUE_MASK, &mStencilValueMaskBack);
|
||||
gl->GetUIntegerv(LOCAL_GL_STENCIL_WRITEMASK, &mStencilWriteMaskFront);
|
||||
gl->GetUIntegerv(LOCAL_GL_STENCIL_BACK_WRITEMASK, &mStencilWriteMaskBack);
|
||||
|
||||
AssertUintParamCorrect(gl, LOCAL_GL_STENCIL_VALUE_MASK, mStencilValueMaskFront);
|
||||
AssertUintParamCorrect(gl, LOCAL_GL_STENCIL_BACK_VALUE_MASK, mStencilValueMaskBack);
|
||||
AssertUintParamCorrect(gl, LOCAL_GL_STENCIL_WRITEMASK, mStencilWriteMaskFront);
|
||||
AssertUintParamCorrect(gl, LOCAL_GL_STENCIL_BACK_WRITEMASK, mStencilWriteMaskBack);
|
||||
|
||||
mDitherEnabled = true;
|
||||
mRasterizerDiscardEnabled = false;
|
||||
mScissorTestEnabled = false;
|
||||
|
||||
// Bindings, etc.
|
||||
mActiveTexture = 0;
|
||||
|
|
|
@ -8,12 +8,14 @@
|
|||
|
||||
#include "WebGLObjectModel.h"
|
||||
|
||||
#include "nsWrapperCache.h"
|
||||
|
||||
#include "mozilla/LinkedList.h"
|
||||
#include "mozilla/CheckedInt.h"
|
||||
#include <map>
|
||||
|
||||
#include "mozilla/CheckedInt.h"
|
||||
#include "mozilla/LinkedList.h"
|
||||
#include "nsWrapperCache.h"
|
||||
#include "WebGLShader.h"
|
||||
#include "WebGLUniformInfo.h"
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
class WebGLShader;
|
||||
|
|
|
@ -1183,11 +1183,9 @@ GLContext::InitWithPrefix(const char *prefix, bool trygl)
|
|||
0, nullptr,
|
||||
true);
|
||||
}
|
||||
}
|
||||
|
||||
if (mInitialized)
|
||||
reporter.SetSuccessful();
|
||||
else {
|
||||
} else {
|
||||
// if initialization fails, ensure all symbols are zero, to avoid hard-to-understand bugs
|
||||
mSymbols.Zero();
|
||||
NS_WARNING("InitWithPrefix failed!");
|
||||
|
|
Загрузка…
Ссылка в новой задаче