зеркало из https://github.com/mozilla/gecko-dev.git
Bug 686732 - Implement minimal-capabilities WebGL mode - r=bjacob
This commit is contained in:
Родитель
9a37a3f8e9
Коммит
e2538cc5de
|
@ -965,6 +965,10 @@ NS_IMETHODIMP
|
|||
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;
|
||||
|
@ -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;
|
||||
|
||||
|
@ -415,6 +433,10 @@ public:
|
|||
GLenum currentGLError;
|
||||
UpdateWebGLErrorAndClearGLError(¤tGLError);
|
||||
}
|
||||
|
||||
bool MinCapabilityMode() const {
|
||||
return mMinCapability;
|
||||
}
|
||||
|
||||
protected:
|
||||
void SetDontKnowIfNeedFakeBlack() {
|
||||
|
@ -456,6 +478,8 @@ protected:
|
|||
bool mResetLayer;
|
||||
bool mVerbose;
|
||||
bool mOptionsFrozen;
|
||||
bool mMinCapability;
|
||||
bool mDisableExtensions;
|
||||
|
||||
WebGLuint mActiveTexture;
|
||||
WebGLenum mWebGLError;
|
||||
|
|
|
@ -1900,7 +1900,61 @@ WebGLContext::GetParameter(PRUint32 pname, nsIVariant **retval)
|
|||
NS_ENSURE_TRUE(wrval, NS_ERROR_FAILURE);
|
||||
|
||||
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;
|
||||
gl->fGetIntegerv(LOCAL_GL_MAX_VERTEX_ATTRIBS, &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);
|
||||
}
|
||||
|
||||
gl->fGetIntegerv(LOCAL_GL_MAX_VERTEX_ATTRIBS, &mGLMaxVertexAttribs);
|
||||
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.
|
||||
gl->fGetIntegerv(LOCAL_GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, &mGLMaxTextureUnits);
|
||||
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);
|
||||
|
||||
gl->fGetIntegerv(LOCAL_GL_MAX_TEXTURE_SIZE, &mGLMaxTextureSize);
|
||||
gl->fGetIntegerv(LOCAL_GL_MAX_CUBE_MAP_TEXTURE_SIZE, &mGLMaxCubeMapTextureSize);
|
||||
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,48 +588,51 @@ WebGLContext::InitAndValidateGL()
|
|||
}
|
||||
#endif
|
||||
|
||||
gl->fGetIntegerv(LOCAL_GL_MAX_TEXTURE_IMAGE_UNITS, &mGLMaxTextureImageUnits);
|
||||
gl->fGetIntegerv(LOCAL_GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS, &mGLMaxVertexTextureImageUnits);
|
||||
|
||||
if (gl->HasES2Compatibility()) {
|
||||
gl->fGetIntegerv(LOCAL_GL_MAX_FRAGMENT_UNIFORM_VECTORS, &mGLMaxFragmentUniformVectors);
|
||||
gl->fGetIntegerv(LOCAL_GL_MAX_VERTEX_UNIFORM_VECTORS, &mGLMaxVertexUniformVectors);
|
||||
gl->fGetIntegerv(LOCAL_GL_MAX_VARYING_VECTORS, &mGLMaxVaryingVectors);
|
||||
if (MinCapabilityMode()) {
|
||||
mGLMaxFragmentUniformVectors = MINVALUE_GL_MAX_FRAGMENT_UNIFORM_VECTORS;
|
||||
mGLMaxVertexUniformVectors = MINVALUE_GL_MAX_VERTEX_UNIFORM_VECTORS;
|
||||
mGLMaxVaryingVectors = MINVALUE_GL_MAX_VARYING_VECTORS;
|
||||
} else {
|
||||
gl->fGetIntegerv(LOCAL_GL_MAX_FRAGMENT_UNIFORM_COMPONENTS, &mGLMaxFragmentUniformVectors);
|
||||
mGLMaxFragmentUniformVectors /= 4;
|
||||
gl->fGetIntegerv(LOCAL_GL_MAX_VERTEX_UNIFORM_COMPONENTS, &mGLMaxVertexUniformVectors);
|
||||
mGLMaxVertexUniformVectors /= 4;
|
||||
if (gl->HasES2Compatibility()) {
|
||||
gl->fGetIntegerv(LOCAL_GL_MAX_FRAGMENT_UNIFORM_VECTORS, &mGLMaxFragmentUniformVectors);
|
||||
gl->fGetIntegerv(LOCAL_GL_MAX_VERTEX_UNIFORM_VECTORS, &mGLMaxVertexUniformVectors);
|
||||
gl->fGetIntegerv(LOCAL_GL_MAX_VARYING_VECTORS, &mGLMaxVaryingVectors);
|
||||
} else {
|
||||
gl->fGetIntegerv(LOCAL_GL_MAX_FRAGMENT_UNIFORM_COMPONENTS, &mGLMaxFragmentUniformVectors);
|
||||
mGLMaxFragmentUniformVectors /= 4;
|
||||
gl->fGetIntegerv(LOCAL_GL_MAX_VERTEX_UNIFORM_COMPONENTS, &mGLMaxVertexUniformVectors);
|
||||
mGLMaxVertexUniformVectors /= 4;
|
||||
|
||||
// we are now going to try to read GL_MAX_VERTEX_OUTPUT_COMPONENTS and GL_MAX_FRAGMENT_INPUT_COMPONENTS,
|
||||
// however these constants only entered the OpenGL standard at OpenGL 3.2. So we will try reading,
|
||||
// and check OpenGL error for INVALID_ENUM.
|
||||
// we are now going to try to read GL_MAX_VERTEX_OUTPUT_COMPONENTS and GL_MAX_FRAGMENT_INPUT_COMPONENTS,
|
||||
// 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->GetAndClearError();
|
||||
if (error != LOCAL_GL_NO_ERROR) {
|
||||
LogMessage("GL error 0x%x occurred during WebGL context initialization!", error);
|
||||
return PR_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);
|
||||
|
||||
error = gl->fGetError();
|
||||
switch (error) {
|
||||
case LOCAL_GL_NO_ERROR:
|
||||
mGLMaxVaryingVectors = NS_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:
|
||||
// before we start, we check that no error already occurred, to prevent hiding it in our subsequent error handling
|
||||
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:
|
||||
// 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);
|
||||
|
||||
error = gl->GetAndClearError();
|
||||
switch (error) {
|
||||
case LOCAL_GL_NO_ERROR:
|
||||
mGLMaxVaryingVectors = NS_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:
|
||||
LogMessage("GL error 0x%x occurred during WebGL context initialization!", error);
|
||||
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
|
||||
|
|
Загрузка…
Ссылка в новой задаче