Bug 686732 - Implement minimal-capabilities WebGL mode - r=bjacob

This commit is contained in:
Christoph Diehl 2011-10-13 08:09:22 -04:00
Родитель 9a37a3f8e9
Коммит e2538cc5de
5 изменённых файлов: 163 добавлений и 46 удалений

Просмотреть файл

@ -966,6 +966,10 @@ WebGLContext::GetExtension(const nsAString& aName, nsIWebGLExtension **retval)
{
*retval = nsnull;
if (mDisableExtensions) {
return NS_OK;
}
// handle simple extensions that don't need custom objects first
WebGLExtensionID ei = WebGLExtensionID_Max;
if (aName.EqualsLiteral("OES_texture_float")) {
@ -1301,6 +1305,12 @@ WebGLActiveInfo::GetName(nsAString & aName)
NS_IMETHODIMP
WebGLContext::GetSupportedExtensions(nsIVariant **retval)
{
*retval = nsnull;
if (mDisableExtensions) {
return NS_OK;
}
nsCOMPtr<nsIWritableVariant> wrval = do_CreateInstance("@mozilla.org/variant;1");
NS_ENSURE_TRUE(wrval, NS_ERROR_FAILURE);

Просмотреть файл

@ -63,6 +63,24 @@
#include "CheckedInt.h"
/*
* Minimum value constants defined in 6.2 State Tables of OpenGL ES - 2.0.25
* https://bugzilla.mozilla.org/show_bug.cgi?id=686732
*
* Exceptions: some of the following values are set to higher values than in the spec because
* the values in the spec are ridiculously low. They are explicitly marked below
*/
#define MINVALUE_GL_MAX_TEXTURE_SIZE 1024 // Different from the spec, which sets it to 64 on page 162
#define MINVALUE_GL_MAX_CUBE_MAP_TEXTURE_SIZE 512 // Different from the spec, which sets it to 16 on page 162
#define MINVALUE_GL_MAX_VERTEX_ATTRIBS 8 // Page 164
#define MINVALUE_GL_MAX_FRAGMENT_UNIFORM_VECTORS 16 // Page 164
#define MINVALUE_GL_MAX_VERTEX_UNIFORM_VECTORS 128 // Page 164
#define MINVALUE_GL_MAX_VARYING_VECTORS 8 // Page 164
#define MINVALUE_GL_MAX_TEXTURE_IMAGE_UNITS 8 // Page 164
#define MINVALUE_GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS 0 // Page 164
#define MINVALUE_GL_MAX_RENDERBUFFER_SIZE 1024 // Different from the spec, which sets it to 1 on page 164
#define MINVALUE_GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS 8 // Page 164
class nsIDocShell;
class nsIPropertyBag;
@ -416,6 +434,10 @@ public:
UpdateWebGLErrorAndClearGLError(&currentGLError);
}
bool MinCapabilityMode() const {
return mMinCapability;
}
protected:
void SetDontKnowIfNeedFakeBlack() {
mFakeBlackStatus = DontKnowIfNeedFakeBlack;
@ -456,6 +478,8 @@ protected:
bool mResetLayer;
bool mVerbose;
bool mOptionsFrozen;
bool mMinCapability;
bool mDisableExtensions;
WebGLuint mActiveTexture;
WebGLenum mWebGLError;

Просмотреть файл

@ -1901,6 +1901,60 @@ WebGLContext::GetParameter(PRUint32 pname, nsIVariant **retval)
MakeContextCurrent();
if (MinCapabilityMode()) {
bool override = true;
switch(pname) {
//
// Single-value params
//
// int
case LOCAL_GL_MAX_VERTEX_ATTRIBS:
wrval->SetAsInt32(MINVALUE_GL_MAX_VERTEX_ATTRIBS);
break;
case LOCAL_GL_MAX_FRAGMENT_UNIFORM_VECTORS:
wrval->SetAsInt32(MINVALUE_GL_MAX_FRAGMENT_UNIFORM_VECTORS);
break;
case LOCAL_GL_MAX_VERTEX_UNIFORM_VECTORS:
wrval->SetAsInt32(MINVALUE_GL_MAX_VERTEX_UNIFORM_VECTORS);
break;
case LOCAL_GL_MAX_VARYING_VECTORS:
wrval->SetAsInt32(MINVALUE_GL_MAX_VARYING_VECTORS);
break;
case LOCAL_GL_MAX_TEXTURE_SIZE:
wrval->SetAsInt32(MINVALUE_GL_MAX_TEXTURE_SIZE);
break;
case LOCAL_GL_MAX_CUBE_MAP_TEXTURE_SIZE:
wrval->SetAsInt32(MINVALUE_GL_MAX_CUBE_MAP_TEXTURE_SIZE);
break;
case LOCAL_GL_MAX_TEXTURE_IMAGE_UNITS:
wrval->SetAsInt32(MINVALUE_GL_MAX_TEXTURE_IMAGE_UNITS);
break;
case LOCAL_GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS:
wrval->SetAsInt32(MINVALUE_GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS);
break;
case LOCAL_GL_MAX_RENDERBUFFER_SIZE:
wrval->SetAsInt32(MINVALUE_GL_MAX_RENDERBUFFER_SIZE);
break;
default:
override = false;
}
if (override) {
*retval = wrval.forget().get();
return NS_OK;
}
}
switch (pname) {
//
// String params

Просмотреть файл

@ -63,7 +63,11 @@ WebGLProgram::UpdateInfo(gl::GLContext *gl)
gl->fGetProgramiv(mName, LOCAL_GL_ACTIVE_ATTRIBUTES, &mAttribCount);
GLint numVertexAttribs;
if (mContext->MinCapabilityMode()) {
numVertexAttribs = MINVALUE_GL_MAX_VERTEX_ATTRIBS;
} else {
gl->fGetIntegerv(LOCAL_GL_MAX_VERTEX_ATTRIBS, &numVertexAttribs);
}
mAttribsInUse.clear();
mAttribsInUse.resize(numVertexAttribs);
@ -503,6 +507,9 @@ WebGLContext::InitAndValidateGL()
return PR_FALSE;
}
mMinCapability = Preferences::GetBool("webgl.min_capability_mode", false);
mDisableExtensions = Preferences::GetBool("webgl.disable-extensions", false);
mActiveTexture = 0;
mWebGLError = LOCAL_GL_NO_ERROR;
@ -533,10 +540,14 @@ WebGLContext::InitAndValidateGL()
gl->fEnableVertexAttribArray(0);
}
if (MinCapabilityMode()) {
mGLMaxVertexAttribs = MINVALUE_GL_MAX_VERTEX_ATTRIBS;
} else {
gl->fGetIntegerv(LOCAL_GL_MAX_VERTEX_ATTRIBS, &mGLMaxVertexAttribs);
}
if (mGLMaxVertexAttribs < 8) {
LogMessage("GL_MAX_VERTEX_ATTRIBS: %d is < 8!", mGLMaxVertexAttribs);
return PR_FALSE;
return false;
}
mAttribBuffers.SetLength(mGLMaxVertexAttribs);
@ -544,17 +555,30 @@ WebGLContext::InitAndValidateGL()
// Note: GL_MAX_TEXTURE_UNITS is fixed at 4 for most desktop hardware,
// even though the hardware supports much more. The
// GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS value is the accurate value.
if (MinCapabilityMode()) {
mGLMaxTextureUnits = MINVALUE_GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS;
} else {
gl->fGetIntegerv(LOCAL_GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, &mGLMaxTextureUnits);
}
if (mGLMaxTextureUnits < 8) {
LogMessage("GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS: %d is < 8!", mGLMaxTextureUnits);
return PR_FALSE;
return false;
}
mBound2DTextures.SetLength(mGLMaxTextureUnits);
mBoundCubeMapTextures.SetLength(mGLMaxTextureUnits);
if (MinCapabilityMode()) {
mGLMaxTextureSize = MINVALUE_GL_MAX_TEXTURE_SIZE;
mGLMaxCubeMapTextureSize = MINVALUE_GL_MAX_CUBE_MAP_TEXTURE_SIZE;
mGLMaxTextureImageUnits = MINVALUE_GL_MAX_TEXTURE_IMAGE_UNITS;
mGLMaxVertexTextureImageUnits = MINVALUE_GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS;
} else {
gl->fGetIntegerv(LOCAL_GL_MAX_TEXTURE_SIZE, &mGLMaxTextureSize);
gl->fGetIntegerv(LOCAL_GL_MAX_CUBE_MAP_TEXTURE_SIZE, &mGLMaxCubeMapTextureSize);
gl->fGetIntegerv(LOCAL_GL_MAX_TEXTURE_IMAGE_UNITS, &mGLMaxTextureImageUnits);
gl->fGetIntegerv(LOCAL_GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS, &mGLMaxVertexTextureImageUnits);
}
#ifdef XP_MACOSX
if (gl->Vendor() == gl::GLContext::VendorIntel) {
@ -564,9 +588,11 @@ WebGLContext::InitAndValidateGL()
}
#endif
gl->fGetIntegerv(LOCAL_GL_MAX_TEXTURE_IMAGE_UNITS, &mGLMaxTextureImageUnits);
gl->fGetIntegerv(LOCAL_GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS, &mGLMaxVertexTextureImageUnits);
if (MinCapabilityMode()) {
mGLMaxFragmentUniformVectors = MINVALUE_GL_MAX_FRAGMENT_UNIFORM_VECTORS;
mGLMaxVertexUniformVectors = MINVALUE_GL_MAX_VERTEX_UNIFORM_VECTORS;
mGLMaxVaryingVectors = MINVALUE_GL_MAX_VARYING_VECTORS;
} else {
if (gl->HasES2Compatibility()) {
gl->fGetIntegerv(LOCAL_GL_MAX_FRAGMENT_UNIFORM_VECTORS, &mGLMaxFragmentUniformVectors);
gl->fGetIntegerv(LOCAL_GL_MAX_VERTEX_UNIFORM_VECTORS, &mGLMaxVertexUniformVectors);
@ -585,7 +611,7 @@ WebGLContext::InitAndValidateGL()
error = gl->GetAndClearError();
if (error != LOCAL_GL_NO_ERROR) {
LogMessage("GL error 0x%x occurred during WebGL context initialization!", error);
return PR_FALSE;
return false;
}
// On the public_webgl list, "problematic GetParameter pnames" thread, the following formula was given:
@ -595,7 +621,7 @@ WebGLContext::InitAndValidateGL()
gl->fGetIntegerv(LOCAL_GL_MAX_VERTEX_OUTPUT_COMPONENTS, &maxVertexOutputComponents);
gl->fGetIntegerv(LOCAL_GL_MAX_FRAGMENT_INPUT_COMPONENTS, &minFragmentInputComponents);
error = gl->fGetError();
error = gl->GetAndClearError();
switch (error) {
case LOCAL_GL_NO_ERROR:
mGLMaxVaryingVectors = NS_MIN(maxVertexOutputComponents, minFragmentInputComponents) / 4;
@ -605,7 +631,8 @@ WebGLContext::InitAndValidateGL()
break;
default:
LogMessage("GL error 0x%x occurred during WebGL context initialization!", error);
return PR_FALSE;
return false;
}
}
}

Просмотреть файл

@ -3287,6 +3287,8 @@ pref("webgl.force_osmesa", false);
pref("webgl.osmesalib", "");
pref("webgl.verbose", false);
pref("webgl.prefer-native-gl", false);
pref("webgl.min_capability_mode", false);
pref("webgl.disable-extensions", false);
#ifdef XP_WIN
// The default TCP send window on Windows is too small, and autotuning only occurs on receive