mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-28 23:31:56 +00:00
Bug 1088345 - Handle possibly-invalid enums for queries. - r=kamidphish
This commit is contained in:
parent
5efb5489a4
commit
8cffb89c2b
@ -1679,31 +1679,22 @@ WebGLContext::InitAndValidateGL()
|
||||
// however these constants only entered the OpenGL standard at OpenGL 3.2. So we will try reading,
|
||||
// and check OpenGL error for INVALID_ENUM.
|
||||
|
||||
// before we start, we check that no error already occurred, to prevent hiding it in our subsequent error handling
|
||||
error = gl->fGetError();
|
||||
if (error != LOCAL_GL_NO_ERROR) {
|
||||
GenerateWarning("GL error 0x%x occurred during WebGL context initialization!", error);
|
||||
return false;
|
||||
}
|
||||
|
||||
// On the public_webgl list, "problematic GetParameter pnames" thread, the following formula was given:
|
||||
// mGLMaxVaryingVectors = min (GL_MAX_VERTEX_OUTPUT_COMPONENTS, GL_MAX_FRAGMENT_INPUT_COMPONENTS) / 4
|
||||
GLint maxVertexOutputComponents,
|
||||
minFragmentInputComponents;
|
||||
gl->fGetIntegerv(LOCAL_GL_MAX_VERTEX_OUTPUT_COMPONENTS, &maxVertexOutputComponents);
|
||||
gl->fGetIntegerv(LOCAL_GL_MAX_FRAGMENT_INPUT_COMPONENTS, &minFragmentInputComponents);
|
||||
GLint maxVertexOutputComponents = 0;
|
||||
GLint maxFragmentInputComponents = 0;
|
||||
|
||||
error = gl->fGetError();
|
||||
switch (error) {
|
||||
case LOCAL_GL_NO_ERROR:
|
||||
mGLMaxVaryingVectors = std::min(maxVertexOutputComponents, minFragmentInputComponents) / 4;
|
||||
break;
|
||||
case LOCAL_GL_INVALID_ENUM:
|
||||
mGLMaxVaryingVectors = 16; // = 64/4, 64 is the min value for maxVertexOutputComponents in OpenGL 3.2 spec
|
||||
break;
|
||||
default:
|
||||
GenerateWarning("GL error 0x%x occurred during WebGL context initialization!", error);
|
||||
return false;
|
||||
const bool ok = (gl->GetPotentialInteger(LOCAL_GL_MAX_VERTEX_OUTPUT_COMPONENTS,
|
||||
&maxVertexOutputComponents) &&
|
||||
gl->GetPotentialInteger(LOCAL_GL_MAX_FRAGMENT_INPUT_COMPONENTS,
|
||||
&maxFragmentInputComponents));
|
||||
|
||||
if (ok) {
|
||||
mGLMaxVaryingVectors = std::min(maxVertexOutputComponents,
|
||||
maxFragmentInputComponents) / 4;
|
||||
} else {
|
||||
mGLMaxVaryingVectors = 16;
|
||||
// = 64/4, 64 is the min value for maxVertexOutputComponents in OpenGL 3.2 spec
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -162,10 +162,9 @@ static const char *sExtensionNames[] = {
|
||||
};
|
||||
|
||||
static bool
|
||||
ParseGLVersion(GLContext* gl, unsigned int* version)
|
||||
ParseGLVersion(GLContext* gl, uint32_t* out_version)
|
||||
{
|
||||
GLenum error = gl->fGetError();
|
||||
if (error != LOCAL_GL_NO_ERROR) {
|
||||
if (gl->fGetError() != LOCAL_GL_NO_ERROR) {
|
||||
MOZ_ASSERT(false, "An OpenGL error has been triggered before.");
|
||||
return false;
|
||||
}
|
||||
@ -175,29 +174,27 @@ ParseGLVersion(GLContext* gl, unsigned int* version)
|
||||
* OpenGL 3.2. The bug is that GetIntegerv(LOCAL_GL_{MAJOR,MINOR}_VERSION)
|
||||
* returns OpenGL 3.2 instead of generating an error.
|
||||
*/
|
||||
if (!gl->IsGLES())
|
||||
{
|
||||
if (!gl->IsGLES()) {
|
||||
/**
|
||||
* OpenGL 3.1 and OpenGL ES 3.0 both introduce GL_{MAJOR,MINOR}_VERSION
|
||||
* with GetIntegerv. So we first try those constants even though we
|
||||
* might not have an OpenGL context supporting them, has this is a
|
||||
* might not have an OpenGL context supporting them, as this is a
|
||||
* better way than parsing GL_VERSION.
|
||||
*/
|
||||
GLint majorVersion = 0;
|
||||
GLint minorVersion = 0;
|
||||
|
||||
gl->fGetIntegerv(LOCAL_GL_MAJOR_VERSION, &majorVersion);
|
||||
gl->fGetIntegerv(LOCAL_GL_MINOR_VERSION, &minorVersion);
|
||||
const bool ok = (gl->GetPotentialInteger(LOCAL_GL_MAJOR_VERSION,
|
||||
&majorVersion) &&
|
||||
gl->GetPotentialInteger(LOCAL_GL_MINOR_VERSION,
|
||||
&minorVersion));
|
||||
|
||||
// If it's not an OpenGL (ES) 3.0 context, we will have an error
|
||||
error = gl->fGetError();
|
||||
while (gl->fGetError() != LOCAL_GL_NO_ERROR);
|
||||
|
||||
if (error == LOCAL_GL_NO_ERROR &&
|
||||
if (ok &&
|
||||
majorVersion > 0 &&
|
||||
minorVersion >= 0)
|
||||
{
|
||||
*version = majorVersion * 100 + minorVersion * 10;
|
||||
*out_version = majorVersion * 100 + minorVersion * 10;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@ -232,8 +229,7 @@ ParseGLVersion(GLContext* gl, unsigned int* version)
|
||||
*/
|
||||
const char* versionString = (const char*)gl->fGetString(LOCAL_GL_VERSION);
|
||||
|
||||
error = gl->fGetError();
|
||||
if (error != LOCAL_GL_NO_ERROR) {
|
||||
if (gl->fGetError() != LOCAL_GL_NO_ERROR) {
|
||||
MOZ_ASSERT(false, "glGetString(GL_VERSION) has generated an error");
|
||||
return false;
|
||||
} else if (!versionString) {
|
||||
@ -248,7 +244,7 @@ ParseGLVersion(GLContext* gl, unsigned int* version)
|
||||
|
||||
const char* itr = versionString;
|
||||
char* end = nullptr;
|
||||
int majorVersion = (int)strtol(itr, &end, 10);
|
||||
auto majorVersion = strtol(itr, &end, 10);
|
||||
|
||||
if (!end) {
|
||||
MOZ_ASSERT(false, "Failed to parse the GL major version number.");
|
||||
@ -263,7 +259,7 @@ ParseGLVersion(GLContext* gl, unsigned int* version)
|
||||
|
||||
end = nullptr;
|
||||
|
||||
int minorVersion = (int)strtol(itr, &end, 10);
|
||||
auto minorVersion = strtol(itr, &end, 10);
|
||||
if (!end) {
|
||||
MOZ_ASSERT(false, "Failed to parse GL's minor version number.");
|
||||
return false;
|
||||
@ -277,7 +273,7 @@ ParseGLVersion(GLContext* gl, unsigned int* version)
|
||||
return false;
|
||||
}
|
||||
|
||||
*version = (unsigned int)(majorVersion * 100 + minorVersion * 10);
|
||||
*out_version = (uint32_t)majorVersion * 100 + (uint32_t)minorVersion * 10;
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -506,8 +502,7 @@ GLContext::InitWithPrefix(const char *prefix, bool trygl)
|
||||
mInitialized = LoadSymbols(&symbols[0], trygl, prefix);
|
||||
MakeCurrent();
|
||||
if (mInitialized) {
|
||||
unsigned int version = 0;
|
||||
|
||||
uint32_t version = 0;
|
||||
ParseGLVersion(this, &version);
|
||||
|
||||
#ifdef MOZ_GL_DEBUG
|
||||
|
@ -276,7 +276,7 @@ public:
|
||||
* Example :
|
||||
* If this a OpenGL 2.1, that will return 210
|
||||
*/
|
||||
inline unsigned int Version() const {
|
||||
inline uint32_t Version() const {
|
||||
return mVersion;
|
||||
}
|
||||
|
||||
@ -318,7 +318,7 @@ protected:
|
||||
* mVersion store the OpenGL's version, multiplied by 100. For example, if
|
||||
* the context is an OpenGL 2.1 context, mVersion value will be 210.
|
||||
*/
|
||||
unsigned int mVersion;
|
||||
uint32_t mVersion;
|
||||
nsCString mVersionString;
|
||||
ContextProfile mProfile;
|
||||
|
||||
@ -660,6 +660,16 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
bool GetPotentialInteger(GLenum pname, GLint* param) {
|
||||
LocalErrorScope localError(*this);
|
||||
|
||||
fGetIntegerv(pname, param);
|
||||
|
||||
GLenum err = localError.GetError();
|
||||
MOZ_ASSERT_IF(err != LOCAL_GL_NO_ERROR, err == LOCAL_GL_INVALID_ENUM);
|
||||
return err == LOCAL_GL_NO_ERROR;
|
||||
}
|
||||
|
||||
private:
|
||||
static void GLAPIENTRY StaticDebugCallback(GLenum source,
|
||||
GLenum type,
|
||||
|
Loading…
Reference in New Issue
Block a user