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
#ifdef XP_MACOSX
if (mAttribBuffers[0].enabled &&
if (gl->WorkAroundDriverBugs() &&
mAttribBuffers[0].enabled &&
!mCurrentProgram->IsAttribInUse(0))
{
return VertexAttrib0Status::EmulatedUninitializedArray;
}
#endif
return (gl->IsGLES2() || mAttribBuffers[0].enabled) ? VertexAttrib0Status::Default
@ -2642,7 +2645,10 @@ WebGLContext::GetProgramParameter(nsIWebGLProgram *pobj, PRUint32 pname, nsIVari
GLint i = 0;
#ifdef XP_MACOSX
// See comment in ValidateProgram below.
i = 1;
if (gl->WorkAroundDriverBugs())
i = 1;
else
gl->fGetProgramiv(progname, pname, &i);
#else
gl->fGetProgramiv(progname, pname, &i);
#endif
@ -4397,8 +4403,10 @@ WebGLContext::ValidateProgram(nsIWebGLProgram *pobj)
#ifdef XP_MACOSX
// 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");
return NS_OK;
if (gl->WorkAroundDriverBugs()) {
LogMessageIfVerbose("validateProgram: implemented as a no-operation on Mac to work around crashes");
return NS_OK;
}
#endif
gl->fValidateProgram(progname);
@ -4506,9 +4514,12 @@ WebGLContext::CompileShader(nsIWebGLShader *sobj)
// 7-bit ASCII range, so we can skip the NS_IsAscii() check.
const nsCString& sourceCString = NS_LossyConvertUTF16toASCII(flatSource);
const PRUint32 maxSourceLength = (PRUint32(1)<<18) - 1;
if (sourceCString.Length() > maxSourceLength)
return ErrorInvalidValue("compileShader: source has more than %d characters", maxSourceLength);
if (gl->WorkAroundDriverBugs()) {
const PRUint32 maxSourceLength = (PRUint32(1)<<18) - 1;
if (sourceCString.Length() > maxSourceLength)
return ErrorInvalidValue("compileShader: source has more than %d characters",
maxSourceLength);
}
const char *s = sourceCString.get();
@ -4524,8 +4535,12 @@ WebGLContext::CompileShader(nsIWebGLShader *sobj)
| SH_ATTRIBUTES_UNIFORMS;
#ifdef XP_MACOSX
// 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;
}
#endif
}

View File

@ -641,7 +641,8 @@ WebGLContext::InitAndValidateGL()
// 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.
#ifdef XP_WIN
if (gl->Vendor() != gl::GLContext::VendorATI)
if (!(gl->WorkAroundDriverBugs() &&
gl->Vendor() == gl::GLContext::VendorATI))
#else
if (true)
#endif

View File

@ -126,6 +126,8 @@ GLContext::InitWithPrefix(const char *prefix, bool trygl)
return true;
}
mWorkAroundDriverBugs = gfxPlatform::GetPlatform()->WorkAroundDriverBugs();
SymLoadStruct symbols[] = {
{ (PRFuncPtr*) &mSymbols.fActiveTexture, { "ActiveTexture", "ActiveTextureARB", 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);
#ifdef XP_MACOSX
if (mVendor == VendorIntel) {
if (mWorkAroundDriverBugs &&
mVendor == VendorIntel) {
// see bug 737182 for 2D textures, bug 684822 for cube map textures.
mMaxTextureSize = NS_MIN(mMaxTextureSize, 4096);
mMaxCubeMapTextureSize = NS_MIN(mMaxCubeMapTextureSize, 512);
@ -634,6 +637,9 @@ CopyAndPadTextureData(const GLvoid* srcBuffer,
bool
GLContext::CanUploadSubTextures()
{
if (!mWorkAroundDriverBugs)
return true;
// There are certain GPUs that we don't want to use glTexSubImage2D on
// because that function can be very slow and/or buggy
if (Renderer() == RendererAdreno200 || Renderer() == RendererAdreno205)
@ -650,6 +656,9 @@ GLContext::CanUploadSubTextures()
bool
GLContext::CanUploadNonPowerOfTwo()
{
if (!mWorkAroundDriverBugs)
return true;
static bool sPowerOfTwoForced;
static bool sPowerOfTwoPrefCached = false;
@ -673,7 +682,8 @@ GLContext::WantsSmallTiles()
return true;
// 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;
// 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
// around an apparent bug
int savedFb = 0;
if (mVendor == VendorQualcomm) {
if (mWorkAroundDriverBugs &&
mVendor == VendorQualcomm)
{
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
// (which it will be, once we assign texture 0 to the color
// attachment)
if (mVendor == VendorQualcomm) {
if (mWorkAroundDriverBugs &&
mVendor == VendorQualcomm) {
fBindFramebuffer(LOCAL_GL_FRAMEBUFFER, savedFb);
}

View File

@ -555,7 +555,8 @@ public:
mMaxTextureSize(0),
mMaxCubeMapTextureSize(0),
mMaxTextureImageSize(0),
mMaxRenderbufferSize(0)
mMaxRenderbufferSize(0),
mWorkAroundDriverBugs(true)
#ifdef DEBUG
, mGLError(LOCAL_GL_NO_ERROR)
#endif
@ -1654,6 +1655,8 @@ protected:
public:
void ClearSafely();
bool WorkAroundDriverBugs() const { return mWorkAroundDriverBugs; }
protected:
nsDataHashtable<nsPtrHashKey<void>, void*> mUserData;
@ -1685,7 +1688,6 @@ protected:
return biggerDimension <= maxAllowed;
}
protected:
nsTArray<nsIntRect> mViewportStack;
nsTArray<nsIntRect> mScissorStack;
@ -1693,10 +1695,12 @@ protected:
GLint mMaxCubeMapTextureSize;
GLint mMaxTextureImageSize;
GLint mMaxRenderbufferSize;
bool mWorkAroundDriverBugs;
bool IsTextureSizeSafeToPassToDriver(GLenum target, GLsizei width, GLsizei height) const {
#ifdef XP_MACOSX
if (mVendor == VendorIntel) {
if (mWorkAroundDriverBugs &&
mVendor == VendorIntel) {
// see bug 737182 for 2D textures, bug 684822 for cube map textures.
// 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

View File

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

View File

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

View File

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