Bug 686735 - 1/2 - Implement no-gfx-driver-workarounds mode - r=joe,ajuma,jgilbert

Part 1: introduce the gfx.work-around-driver-bugs preference and handle most existing workarounds
This commit is contained in:
Benoit Jacob 2012-04-10 11:49:10 -04:00
parent 5203026f2f
commit dc36f05c94
7 changed files with 56 additions and 16 deletions

View File

@ -1375,9 +1375,12 @@ WebGLContext::WhatDoesVertexAttrib0Need()
// work around Mac OSX crash, see bug 631420 // work around Mac OSX crash, see bug 631420
#ifdef XP_MACOSX #ifdef XP_MACOSX
if (mAttribBuffers[0].enabled && if (gl->WorkAroundDriverBugs() &&
mAttribBuffers[0].enabled &&
!mCurrentProgram->IsAttribInUse(0)) !mCurrentProgram->IsAttribInUse(0))
{
return VertexAttrib0Status::EmulatedUninitializedArray; return VertexAttrib0Status::EmulatedUninitializedArray;
}
#endif #endif
return (gl->IsGLES2() || mAttribBuffers[0].enabled) ? VertexAttrib0Status::Default return (gl->IsGLES2() || mAttribBuffers[0].enabled) ? VertexAttrib0Status::Default
@ -2642,7 +2645,10 @@ WebGLContext::GetProgramParameter(nsIWebGLProgram *pobj, PRUint32 pname, nsIVari
GLint i = 0; GLint i = 0;
#ifdef XP_MACOSX #ifdef XP_MACOSX
// See comment in ValidateProgram below. // See comment in ValidateProgram below.
i = 1; if (gl->WorkAroundDriverBugs())
i = 1;
else
gl->fGetProgramiv(progname, pname, &i);
#else #else
gl->fGetProgramiv(progname, pname, &i); gl->fGetProgramiv(progname, pname, &i);
#endif #endif
@ -4397,8 +4403,10 @@ WebGLContext::ValidateProgram(nsIWebGLProgram *pobj)
#ifdef XP_MACOSX #ifdef XP_MACOSX
// see bug 593867 for NVIDIA and bug 657201 for ATI. The latter is confirmed with Mac OS 10.6.7 // see bug 593867 for NVIDIA and bug 657201 for ATI. The latter is confirmed with Mac OS 10.6.7
LogMessageIfVerbose("validateProgram: implemented as a no-operation on Mac to work around crashes"); if (gl->WorkAroundDriverBugs()) {
return NS_OK; LogMessageIfVerbose("validateProgram: implemented as a no-operation on Mac to work around crashes");
return NS_OK;
}
#endif #endif
gl->fValidateProgram(progname); gl->fValidateProgram(progname);
@ -4506,9 +4514,12 @@ WebGLContext::CompileShader(nsIWebGLShader *sobj)
// 7-bit ASCII range, so we can skip the NS_IsAscii() check. // 7-bit ASCII range, so we can skip the NS_IsAscii() check.
const nsCString& sourceCString = NS_LossyConvertUTF16toASCII(flatSource); const nsCString& sourceCString = NS_LossyConvertUTF16toASCII(flatSource);
const PRUint32 maxSourceLength = (PRUint32(1)<<18) - 1; if (gl->WorkAroundDriverBugs()) {
if (sourceCString.Length() > maxSourceLength) const PRUint32 maxSourceLength = (PRUint32(1)<<18) - 1;
return ErrorInvalidValue("compileShader: source has more than %d characters", maxSourceLength); if (sourceCString.Length() > maxSourceLength)
return ErrorInvalidValue("compileShader: source has more than %d characters",
maxSourceLength);
}
const char *s = sourceCString.get(); const char *s = sourceCString.get();
@ -4524,8 +4535,12 @@ WebGLContext::CompileShader(nsIWebGLShader *sobj)
| SH_ATTRIBUTES_UNIFORMS; | SH_ATTRIBUTES_UNIFORMS;
#ifdef XP_MACOSX #ifdef XP_MACOSX
// work around bug 665578 // work around bug 665578
if (!nsCocoaFeatures::OnLionOrLater() && gl->Vendor() == gl::GLContext::VendorATI) if (gl->WorkAroundDriverBugs() &&
!nsCocoaFeatures::OnLionOrLater() &&
gl->Vendor() == gl::GLContext::VendorATI)
{
compileOptions |= SH_EMULATE_BUILT_IN_FUNCTIONS; compileOptions |= SH_EMULATE_BUILT_IN_FUNCTIONS;
}
#endif #endif
} }

View File

@ -641,7 +641,8 @@ WebGLContext::InitAndValidateGL()
// http://www.gamedev.net/community/forums/topic.asp?topic_id=525643 // http://www.gamedev.net/community/forums/topic.asp?topic_id=525643
// Also, if the ATI/Windows driver implements a recent GL spec version, this shouldn't be needed anyway. // Also, if the ATI/Windows driver implements a recent GL spec version, this shouldn't be needed anyway.
#ifdef XP_WIN #ifdef XP_WIN
if (gl->Vendor() != gl::GLContext::VendorATI) if (!(gl->WorkAroundDriverBugs() &&
gl->Vendor() == gl::GLContext::VendorATI))
#else #else
if (true) if (true)
#endif #endif

View File

@ -126,6 +126,8 @@ GLContext::InitWithPrefix(const char *prefix, bool trygl)
return true; return true;
} }
mWorkAroundDriverBugs = gfxPlatform::GetPlatform()->WorkAroundDriverBugs();
SymLoadStruct symbols[] = { SymLoadStruct symbols[] = {
{ (PRFuncPtr*) &mSymbols.fActiveTexture, { "ActiveTexture", "ActiveTextureARB", NULL } }, { (PRFuncPtr*) &mSymbols.fActiveTexture, { "ActiveTexture", "ActiveTextureARB", NULL } },
{ (PRFuncPtr*) &mSymbols.fAttachShader, { "AttachShader", "AttachShaderARB", NULL } }, { (PRFuncPtr*) &mSymbols.fAttachShader, { "AttachShader", "AttachShaderARB", NULL } },
@ -501,7 +503,8 @@ GLContext::InitWithPrefix(const char *prefix, bool trygl)
fGetIntegerv(LOCAL_GL_MAX_RENDERBUFFER_SIZE, &mMaxRenderbufferSize); fGetIntegerv(LOCAL_GL_MAX_RENDERBUFFER_SIZE, &mMaxRenderbufferSize);
#ifdef XP_MACOSX #ifdef XP_MACOSX
if (mVendor == VendorIntel) { if (mWorkAroundDriverBugs &&
mVendor == VendorIntel) {
// see bug 737182 for 2D textures, bug 684822 for cube map textures. // see bug 737182 for 2D textures, bug 684822 for cube map textures.
mMaxTextureSize = NS_MIN(mMaxTextureSize, 4096); mMaxTextureSize = NS_MIN(mMaxTextureSize, 4096);
mMaxCubeMapTextureSize = NS_MIN(mMaxCubeMapTextureSize, 512); mMaxCubeMapTextureSize = NS_MIN(mMaxCubeMapTextureSize, 512);
@ -634,6 +637,9 @@ CopyAndPadTextureData(const GLvoid* srcBuffer,
bool bool
GLContext::CanUploadSubTextures() GLContext::CanUploadSubTextures()
{ {
if (!mWorkAroundDriverBugs)
return true;
// There are certain GPUs that we don't want to use glTexSubImage2D on // There are certain GPUs that we don't want to use glTexSubImage2D on
// because that function can be very slow and/or buggy // because that function can be very slow and/or buggy
if (Renderer() == RendererAdreno200 || Renderer() == RendererAdreno205) if (Renderer() == RendererAdreno200 || Renderer() == RendererAdreno205)
@ -650,6 +656,9 @@ GLContext::CanUploadSubTextures()
bool bool
GLContext::CanUploadNonPowerOfTwo() GLContext::CanUploadNonPowerOfTwo()
{ {
if (!mWorkAroundDriverBugs)
return true;
static bool sPowerOfTwoForced; static bool sPowerOfTwoForced;
static bool sPowerOfTwoPrefCached = false; static bool sPowerOfTwoPrefCached = false;
@ -673,7 +682,8 @@ GLContext::WantsSmallTiles()
return true; return true;
// We can't use small tiles on the SGX 540, because of races in texture upload. // We can't use small tiles on the SGX 540, because of races in texture upload.
if (Renderer() == RendererSGX540) if (mWorkAroundDriverBugs &&
Renderer() == RendererSGX540)
return false; return false;
// Don't use small tiles otherwise. (If we implement incremental texture upload, // Don't use small tiles otherwise. (If we implement incremental texture upload,
@ -2065,7 +2075,9 @@ GLContext::BlitTextureImage(TextureImage *aSrc, const nsIntRect& aSrcRect,
// only save/restore this stuff on Qualcomm Adreno, to work // only save/restore this stuff on Qualcomm Adreno, to work
// around an apparent bug // around an apparent bug
int savedFb = 0; int savedFb = 0;
if (mVendor == VendorQualcomm) { if (mWorkAroundDriverBugs &&
mVendor == VendorQualcomm)
{
fGetIntegerv(LOCAL_GL_FRAMEBUFFER_BINDING, &savedFb); fGetIntegerv(LOCAL_GL_FRAMEBUFFER_BINDING, &savedFb);
} }
@ -2200,7 +2212,8 @@ GLContext::BlitTextureImage(TextureImage *aSrc, const nsIntRect& aSrcRect,
// we enable scissor test while the current FBO is invalid // we enable scissor test while the current FBO is invalid
// (which it will be, once we assign texture 0 to the color // (which it will be, once we assign texture 0 to the color
// attachment) // attachment)
if (mVendor == VendorQualcomm) { if (mWorkAroundDriverBugs &&
mVendor == VendorQualcomm) {
fBindFramebuffer(LOCAL_GL_FRAMEBUFFER, savedFb); fBindFramebuffer(LOCAL_GL_FRAMEBUFFER, savedFb);
} }

View File

@ -555,7 +555,8 @@ public:
mMaxTextureSize(0), mMaxTextureSize(0),
mMaxCubeMapTextureSize(0), mMaxCubeMapTextureSize(0),
mMaxTextureImageSize(0), mMaxTextureImageSize(0),
mMaxRenderbufferSize(0) mMaxRenderbufferSize(0),
mWorkAroundDriverBugs(true)
#ifdef DEBUG #ifdef DEBUG
, mGLError(LOCAL_GL_NO_ERROR) , mGLError(LOCAL_GL_NO_ERROR)
#endif #endif
@ -1654,6 +1655,8 @@ protected:
public: public:
void ClearSafely(); void ClearSafely();
bool WorkAroundDriverBugs() const { return mWorkAroundDriverBugs; }
protected: protected:
nsDataHashtable<nsPtrHashKey<void>, void*> mUserData; nsDataHashtable<nsPtrHashKey<void>, void*> mUserData;
@ -1685,7 +1688,6 @@ protected:
return biggerDimension <= maxAllowed; return biggerDimension <= maxAllowed;
} }
protected:
nsTArray<nsIntRect> mViewportStack; nsTArray<nsIntRect> mViewportStack;
nsTArray<nsIntRect> mScissorStack; nsTArray<nsIntRect> mScissorStack;
@ -1693,10 +1695,12 @@ protected:
GLint mMaxCubeMapTextureSize; GLint mMaxCubeMapTextureSize;
GLint mMaxTextureImageSize; GLint mMaxTextureImageSize;
GLint mMaxRenderbufferSize; GLint mMaxRenderbufferSize;
bool mWorkAroundDriverBugs;
bool IsTextureSizeSafeToPassToDriver(GLenum target, GLsizei width, GLsizei height) const { bool IsTextureSizeSafeToPassToDriver(GLenum target, GLsizei width, GLsizei height) const {
#ifdef XP_MACOSX #ifdef XP_MACOSX
if (mVendor == VendorIntel) { if (mWorkAroundDriverBugs &&
mVendor == VendorIntel) {
// see bug 737182 for 2D textures, bug 684822 for cube map textures. // see bug 737182 for 2D textures, bug 684822 for cube map textures.
// some drivers handle incorrectly some large texture sizes that are below the // some drivers handle incorrectly some large texture sizes that are below the
// max texture size that they report. So we check ourselves against our own values // max texture size that they report. So we check ourselves against our own values

View File

@ -336,6 +336,8 @@ gfxPlatform::Init()
gPlatform->mFontPrefsObserver = new FontPrefsObserver(); gPlatform->mFontPrefsObserver = new FontPrefsObserver();
Preferences::AddStrongObservers(gPlatform->mFontPrefsObserver, kObservedPrefs); Preferences::AddStrongObservers(gPlatform->mFontPrefsObserver, kObservedPrefs);
gPlatform->mWorkAroundDriverBugs = Preferences::GetBool("gfx.work-around-driver-bugs", true);
// Force registration of the gfx component, thus arranging for // Force registration of the gfx component, thus arranging for
// ::Shutdown to be called. // ::Shutdown to be called.
nsCOMPtr<nsISupports> forceReg nsCOMPtr<nsISupports> forceReg

View File

@ -455,6 +455,8 @@ public:
*/ */
static PRLogModuleInfo* GetLog(eGfxLog aWhichLog); static PRLogModuleInfo* GetLog(eGfxLog aWhichLog);
bool WorkAroundDriverBugs() const { return mWorkAroundDriverBugs; }
protected: protected:
gfxPlatform(); gfxPlatform();
virtual ~gfxPlatform(); virtual ~gfxPlatform();
@ -493,6 +495,7 @@ private:
nsCOMPtr<nsIObserver> mSRGBOverrideObserver; nsCOMPtr<nsIObserver> mSRGBOverrideObserver;
nsCOMPtr<nsIObserver> mFontPrefsObserver; nsCOMPtr<nsIObserver> mFontPrefsObserver;
mozilla::widget::GfxInfoCollector<gfxPlatform> mAzureBackendCollector; mozilla::widget::GfxInfoCollector<gfxPlatform> mAzureBackendCollector;
bool mWorkAroundDriverBugs;
}; };
#endif /* GFX_PLATFORM_H */ #endif /* GFX_PLATFORM_H */

View File

@ -245,6 +245,8 @@ pref("gfx.canvas.azure.enabled", true);
pref("gfx.textures.poweroftwo.force-enabled", false); pref("gfx.textures.poweroftwo.force-enabled", false);
#endif #endif
pref("gfx.work-around-driver-bugs", true);
pref("accessibility.browsewithcaret", false); pref("accessibility.browsewithcaret", false);
pref("accessibility.warn_on_browsewithcaret", true); pref("accessibility.warn_on_browsewithcaret", true);