зеркало из 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)
|
WebGLContext::GetExtension(const nsAString& aName, nsIWebGLExtension **retval)
|
||||||
{
|
{
|
||||||
*retval = nsnull;
|
*retval = nsnull;
|
||||||
|
|
||||||
|
if (mDisableExtensions) {
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
// handle simple extensions that don't need custom objects first
|
// handle simple extensions that don't need custom objects first
|
||||||
WebGLExtensionID ei = WebGLExtensionID_Max;
|
WebGLExtensionID ei = WebGLExtensionID_Max;
|
||||||
|
@ -1301,6 +1305,12 @@ WebGLActiveInfo::GetName(nsAString & aName)
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
WebGLContext::GetSupportedExtensions(nsIVariant **retval)
|
WebGLContext::GetSupportedExtensions(nsIVariant **retval)
|
||||||
{
|
{
|
||||||
|
*retval = nsnull;
|
||||||
|
|
||||||
|
if (mDisableExtensions) {
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
nsCOMPtr<nsIWritableVariant> wrval = do_CreateInstance("@mozilla.org/variant;1");
|
nsCOMPtr<nsIWritableVariant> wrval = do_CreateInstance("@mozilla.org/variant;1");
|
||||||
NS_ENSURE_TRUE(wrval, NS_ERROR_FAILURE);
|
NS_ENSURE_TRUE(wrval, NS_ERROR_FAILURE);
|
||||||
|
|
||||||
|
|
|
@ -63,6 +63,24 @@
|
||||||
|
|
||||||
#include "CheckedInt.h"
|
#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 nsIDocShell;
|
||||||
class nsIPropertyBag;
|
class nsIPropertyBag;
|
||||||
|
|
||||||
|
@ -415,6 +433,10 @@ public:
|
||||||
GLenum currentGLError;
|
GLenum currentGLError;
|
||||||
UpdateWebGLErrorAndClearGLError(¤tGLError);
|
UpdateWebGLErrorAndClearGLError(¤tGLError);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool MinCapabilityMode() const {
|
||||||
|
return mMinCapability;
|
||||||
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void SetDontKnowIfNeedFakeBlack() {
|
void SetDontKnowIfNeedFakeBlack() {
|
||||||
|
@ -456,6 +478,8 @@ protected:
|
||||||
bool mResetLayer;
|
bool mResetLayer;
|
||||||
bool mVerbose;
|
bool mVerbose;
|
||||||
bool mOptionsFrozen;
|
bool mOptionsFrozen;
|
||||||
|
bool mMinCapability;
|
||||||
|
bool mDisableExtensions;
|
||||||
|
|
||||||
WebGLuint mActiveTexture;
|
WebGLuint mActiveTexture;
|
||||||
WebGLenum mWebGLError;
|
WebGLenum mWebGLError;
|
||||||
|
|
|
@ -1900,7 +1900,61 @@ WebGLContext::GetParameter(PRUint32 pname, nsIVariant **retval)
|
||||||
NS_ENSURE_TRUE(wrval, NS_ERROR_FAILURE);
|
NS_ENSURE_TRUE(wrval, NS_ERROR_FAILURE);
|
||||||
|
|
||||||
MakeContextCurrent();
|
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) {
|
switch (pname) {
|
||||||
//
|
//
|
||||||
// String params
|
// String params
|
||||||
|
|
|
@ -63,7 +63,11 @@ WebGLProgram::UpdateInfo(gl::GLContext *gl)
|
||||||
gl->fGetProgramiv(mName, LOCAL_GL_ACTIVE_ATTRIBUTES, &mAttribCount);
|
gl->fGetProgramiv(mName, LOCAL_GL_ACTIVE_ATTRIBUTES, &mAttribCount);
|
||||||
|
|
||||||
GLint numVertexAttribs;
|
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.clear();
|
||||||
mAttribsInUse.resize(numVertexAttribs);
|
mAttribsInUse.resize(numVertexAttribs);
|
||||||
|
|
||||||
|
@ -503,6 +507,9 @@ WebGLContext::InitAndValidateGL()
|
||||||
return PR_FALSE;
|
return PR_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mMinCapability = Preferences::GetBool("webgl.min_capability_mode", false);
|
||||||
|
mDisableExtensions = Preferences::GetBool("webgl.disable-extensions", false);
|
||||||
|
|
||||||
mActiveTexture = 0;
|
mActiveTexture = 0;
|
||||||
mWebGLError = LOCAL_GL_NO_ERROR;
|
mWebGLError = LOCAL_GL_NO_ERROR;
|
||||||
|
|
||||||
|
@ -533,10 +540,14 @@ WebGLContext::InitAndValidateGL()
|
||||||
gl->fEnableVertexAttribArray(0);
|
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) {
|
if (mGLMaxVertexAttribs < 8) {
|
||||||
LogMessage("GL_MAX_VERTEX_ATTRIBS: %d is < 8!", mGLMaxVertexAttribs);
|
LogMessage("GL_MAX_VERTEX_ATTRIBS: %d is < 8!", mGLMaxVertexAttribs);
|
||||||
return PR_FALSE;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
mAttribBuffers.SetLength(mGLMaxVertexAttribs);
|
mAttribBuffers.SetLength(mGLMaxVertexAttribs);
|
||||||
|
@ -544,17 +555,30 @@ WebGLContext::InitAndValidateGL()
|
||||||
// Note: GL_MAX_TEXTURE_UNITS is fixed at 4 for most desktop hardware,
|
// Note: GL_MAX_TEXTURE_UNITS is fixed at 4 for most desktop hardware,
|
||||||
// even though the hardware supports much more. The
|
// even though the hardware supports much more. The
|
||||||
// GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS value is the accurate value.
|
// 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) {
|
if (mGLMaxTextureUnits < 8) {
|
||||||
LogMessage("GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS: %d is < 8!", mGLMaxTextureUnits);
|
LogMessage("GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS: %d is < 8!", mGLMaxTextureUnits);
|
||||||
return PR_FALSE;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
mBound2DTextures.SetLength(mGLMaxTextureUnits);
|
mBound2DTextures.SetLength(mGLMaxTextureUnits);
|
||||||
mBoundCubeMapTextures.SetLength(mGLMaxTextureUnits);
|
mBoundCubeMapTextures.SetLength(mGLMaxTextureUnits);
|
||||||
|
|
||||||
gl->fGetIntegerv(LOCAL_GL_MAX_TEXTURE_SIZE, &mGLMaxTextureSize);
|
if (MinCapabilityMode()) {
|
||||||
gl->fGetIntegerv(LOCAL_GL_MAX_CUBE_MAP_TEXTURE_SIZE, &mGLMaxCubeMapTextureSize);
|
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
|
#ifdef XP_MACOSX
|
||||||
if (gl->Vendor() == gl::GLContext::VendorIntel) {
|
if (gl->Vendor() == gl::GLContext::VendorIntel) {
|
||||||
|
@ -564,48 +588,51 @@ WebGLContext::InitAndValidateGL()
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
gl->fGetIntegerv(LOCAL_GL_MAX_TEXTURE_IMAGE_UNITS, &mGLMaxTextureImageUnits);
|
if (MinCapabilityMode()) {
|
||||||
gl->fGetIntegerv(LOCAL_GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS, &mGLMaxVertexTextureImageUnits);
|
mGLMaxFragmentUniformVectors = MINVALUE_GL_MAX_FRAGMENT_UNIFORM_VECTORS;
|
||||||
|
mGLMaxVertexUniformVectors = MINVALUE_GL_MAX_VERTEX_UNIFORM_VECTORS;
|
||||||
if (gl->HasES2Compatibility()) {
|
mGLMaxVaryingVectors = MINVALUE_GL_MAX_VARYING_VECTORS;
|
||||||
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 {
|
} else {
|
||||||
gl->fGetIntegerv(LOCAL_GL_MAX_FRAGMENT_UNIFORM_COMPONENTS, &mGLMaxFragmentUniformVectors);
|
if (gl->HasES2Compatibility()) {
|
||||||
mGLMaxFragmentUniformVectors /= 4;
|
gl->fGetIntegerv(LOCAL_GL_MAX_FRAGMENT_UNIFORM_VECTORS, &mGLMaxFragmentUniformVectors);
|
||||||
gl->fGetIntegerv(LOCAL_GL_MAX_VERTEX_UNIFORM_COMPONENTS, &mGLMaxVertexUniformVectors);
|
gl->fGetIntegerv(LOCAL_GL_MAX_VERTEX_UNIFORM_VECTORS, &mGLMaxVertexUniformVectors);
|
||||||
mGLMaxVertexUniformVectors /= 4;
|
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,
|
// 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,
|
// however these constants only entered the OpenGL standard at OpenGL 3.2. So we will try reading,
|
||||||
// and check OpenGL error for INVALID_ENUM.
|
// 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
|
// before we start, we check that no error already occurred, to prevent hiding it in our subsequent error handling
|
||||||
error = gl->GetAndClearError();
|
error = gl->GetAndClearError();
|
||||||
if (error != LOCAL_GL_NO_ERROR) {
|
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:
|
|
||||||
LogMessage("GL error 0x%x occurred during WebGL context initialization!", 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.osmesalib", "");
|
||||||
pref("webgl.verbose", false);
|
pref("webgl.verbose", false);
|
||||||
pref("webgl.prefer-native-gl", false);
|
pref("webgl.prefer-native-gl", false);
|
||||||
|
pref("webgl.min_capability_mode", false);
|
||||||
|
pref("webgl.disable-extensions", false);
|
||||||
|
|
||||||
#ifdef XP_WIN
|
#ifdef XP_WIN
|
||||||
// The default TCP send window on Windows is too small, and autotuning only occurs on receive
|
// The default TCP send window on Windows is too small, and autotuning only occurs on receive
|
||||||
|
|
Загрузка…
Ссылка в новой задаче