Bug 1288446 - Call glCheckFramebufferStatus after glFramebufferTexture2D to avoid driver crash; r?jrmuizel
Some PowerVR SGX540 devices running Android 4.0 were crashing when
uploading texture data with glTexSubImage2D. This was unearthed by a
Skia upgrade which removed what should have been an unnecessary OpenGL
call. This reinstates the OpenGL call which prevents the crash, but at a
GLContext level rather than in Skia.
MozReview-Commit-ID: Dub8VSs2Dzd
--- a/gfx/gl/GLContext.cpp
+++ b/gfx/gl/GLContext.cpp
@@ -466,16 +466,17 @@ GLContext::GLContext(CreateContextFlags
mMaxTextureSize(0),
mMaxCubeMapTextureSize(0),
mMaxTextureImageSize(0),
mMaxRenderbufferSize(0),
mMaxSamples(0),
mNeedsTextureSizeChecks(false),
mNeedsFlushBeforeDeleteFB(false),
mTextureAllocCrashesOnMapFailure(false),
+ mNeedsCheckAfterAttachTextureToFb(false),
mWorkAroundDriverBugs(true),
mHeavyGLCallsSinceLastFlush(false)
{
mMaxViewportDims[0] = 0;
mMaxViewportDims[1] = 0;
mOwningThreadId = PlatformThread::CurrentId();
}
@@ -1058,16 +1059,27 @@ GLContext::InitWithPrefixImpl(const char
Renderer() == GLRenderer::AdrenoTM320 ||
Renderer() == GLRenderer::AdrenoTM330) &&
AndroidBridge::Bridge()->GetAPIVersion() < 21) {
// Bug 1164027. Driver crashes when functions such as
// glTexImage2D fail due to virtual memory exhaustion.
mTextureAllocCrashesOnMapFailure = true;
}
#endif
+#if MOZ_WIDGET_ANDROID
+ if (mWorkAroundDriverBugs &&
+ Renderer() == GLRenderer::SGX540 &&
+ AndroidBridge::Bridge()->GetAPIVersion() <= 15) {
+ // Bug 1288446. Driver sometimes crashes when uploading data to a
+ // texture if the render target has changed since the texture was
+ // rendered from. Calling glCheckFramebufferStatus after
+ // glFramebufferTexture2D prevents the crash.
+ mNeedsCheckAfterAttachTextureToFb = true;
+ }
+#endif
mMaxTextureImageSize = mMaxTextureSize;
if (IsSupported(GLFeature::framebuffer_multisample)) {
fGetIntegerv(LOCAL_GL_MAX_SAMPLES, (GLint*)&mMaxSamples);
}
////////////////////////////////////////////////////////////////////////////
--- a/gfx/gl/GLContext.h
+++ b/gfx/gl/GLContext.h
@@ -1962,16 +1962,19 @@ public:
mSymbols.fFramebufferRenderbuffer(target, attachmentPoint, renderbufferTarget, renderbuffer);
AFTER_GL_CALL;
}
void fFramebufferTexture2D(GLenum target, GLenum attachmentPoint, GLenum textureTarget, GLuint texture, GLint level) {
BEFORE_GL_CALL;
mSymbols.fFramebufferTexture2D(target, attachmentPoint, textureTarget, texture, level);
AFTER_GL_CALL;
+ if (mNeedsCheckAfterAttachTextureToFb) {
+ fCheckFramebufferStatus(target);
+ }
}
void fFramebufferTextureLayer(GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer) {
BEFORE_GL_CALL;
ASSERT_SYMBOL_PRESENT(fFramebufferTextureLayer);
mSymbols.fFramebufferTextureLayer(target, attachment, texture, level, layer);
AFTER_GL_CALL;
}
@@ -3526,16 +3529,17 @@ protected:
GLint mMaxCubeMapTextureSize;
GLint mMaxTextureImageSize;
GLint mMaxRenderbufferSize;
GLint mMaxViewportDims[2];
GLsizei mMaxSamples;
bool mNeedsTextureSizeChecks;
bool mNeedsFlushBeforeDeleteFB;
bool mTextureAllocCrashesOnMapFailure;
+ bool mNeedsCheckAfterAttachTextureToFb;
bool mWorkAroundDriverBugs;
bool IsTextureSizeSafeToPassToDriver(GLenum target, GLsizei width, GLsizei height) const {
if (mNeedsTextureSizeChecks) {
// some drivers incorrectly handle some large texture sizes that are below the
// max texture size that they report. So we check ourselves against our own values
// (mMax[CubeMap]TextureSize).
// see bug 737182 for Mac Intel 2D textures