Work around a y-invert bug on Macs w/ Intel GPU

On Macs running OS X 10.6 and 10.7 with Intel HD Graphics 3000, some
screens or parts of the screen are displayed upside down. The exact
conditions/sequence that triggers this aren't known yet; I haven't
been able to reproduce it in a standalone test. This also means I
don't know whether it is a driver bug, or a bug in the OpenglRender or
Translator code that just happens to work elsewhere.

Thanks to zhiyuan.li@intel.com for a patch this change is based on.

Change-Id: I04823773818d3b587a6951be48e70b03804b33d0
This commit is contained in:
Jesse Hall
2012-03-06 13:43:50 -08:00
parent 767d089487
commit 9322c5cb25
8 changed files with 55 additions and 14 deletions

View File

@@ -31,6 +31,13 @@ void GLEScmContext::init() {
m_texCoords = new GLESpointer[s_glSupport.maxTexUnits]; m_texCoords = new GLESpointer[s_glSupport.maxTexUnits];
m_map[GL_TEXTURE_COORD_ARRAY] = &m_texCoords[m_clientActiveTexture]; m_map[GL_TEXTURE_COORD_ARRAY] = &m_texCoords[m_clientActiveTexture];
const char* baseRenderer = (const char*)dispatcher().glGetString(GL_RENDERER);
size_t baseRendererLen = strlen(baseRenderer);
s_glRenderer.clear();
s_glRenderer.reserve(19 + baseRendererLen);
s_glRenderer.append("OpenGL ES-CM 1.1 (", 18);
s_glRenderer.append(baseRenderer, baseRendererLen);
s_glRenderer.append(")", 1);
} }
m_initialized = true; m_initialized = true;
} }

View File

@@ -248,15 +248,14 @@ GL_API GLenum GL_APIENTRY glGetError(void) {
GL_API const GLubyte * GL_APIENTRY glGetString( GLenum name) { GL_API const GLubyte * GL_APIENTRY glGetString( GLenum name) {
GET_CTX_RET(NULL) GET_CTX_RET(NULL)
static GLubyte VENDOR[] = "Google"; static const GLubyte VENDOR[] = "Google";
static GLubyte RENDERER[] = "OpenGL ES-CM 1.1"; static const GLubyte VERSION[] = "OpenGL ES-CM 1.1";
static GLubyte VERSION[] = "OpenGL ES-CM 1.1";
switch(name) { switch(name) {
case GL_VENDOR: case GL_VENDOR:
return VENDOR; return VENDOR;
case GL_RENDERER: case GL_RENDERER:
return RENDERER; return (const GLubyte*)ctx->getRendererString();
case GL_VERSION: case GL_VERSION:
return VERSION; return VERSION;
case GL_EXTENSIONS: case GL_EXTENSIONS:

View File

@@ -27,6 +27,14 @@ void GLESv2Context::init() {
m_map[i] = new GLESpointer(); m_map[i] = new GLESpointer();
} }
setAttribute0value(0.0, 0.0, 0.0, 1.0); setAttribute0value(0.0, 0.0, 0.0, 1.0);
const char* baseRenderer = (const char*)dispatcher().glGetString(GL_RENDERER);
size_t baseRendererLen = strlen(baseRenderer);
s_glRenderer.clear();
s_glRenderer.reserve(16 + baseRendererLen);
s_glRenderer.append("OpenGL ES 2.0 (", 15);
s_glRenderer.append(baseRenderer, baseRendererLen);
s_glRenderer.append(")", 1);
} }
m_initialized = true; m_initialized = true;
} }

View File

@@ -1316,15 +1316,14 @@ GL_APICALL void GL_APIENTRY glGetShaderSource(GLuint shader, GLsizei bufsize, G
GL_APICALL const GLubyte* GL_APIENTRY glGetString(GLenum name){ GL_APICALL const GLubyte* GL_APIENTRY glGetString(GLenum name){
GET_CTX_RET(NULL) GET_CTX_RET(NULL)
static GLubyte VENDOR[] = "Google"; static const GLubyte VENDOR[] = "Google";
static GLubyte RENDERER[] = "OpenGL ES 2.0"; static const GLubyte VERSION[] = "OpenGL ES 2.0";
static GLubyte VERSION[] = "OpenGL ES 2.0"; static const GLubyte SHADING[] = "OpenGL ES GLSL ES 1.0.17";
static GLubyte SHADING[] = "OpenGL ES GLSL ES 1.0.17";
switch(name) { switch(name) {
case GL_VENDOR: case GL_VENDOR:
return VENDOR; return VENDOR;
case GL_RENDERER: case GL_RENDERER:
return RENDERER; return (const GLubyte*)ctx->getRendererString();
case GL_VERSION: case GL_VERSION:
return VERSION; return VERSION;
case GL_SHADING_LANGUAGE_VERSION: case GL_SHADING_LANGUAGE_VERSION:

View File

@@ -70,6 +70,7 @@ void GLESConversionArrays::operator++(){
GLDispatch GLEScontext::s_glDispatch; GLDispatch GLEScontext::s_glDispatch;
android::Mutex GLEScontext::s_lock; android::Mutex GLEScontext::s_lock;
std::string* GLEScontext::s_glExtensions= NULL; std::string* GLEScontext::s_glExtensions= NULL;
std::string GLEScontext::s_glRenderer;
GLSupport GLEScontext::s_glSupport; GLSupport GLEScontext::s_glSupport;
Version::Version():m_major(0), Version::Version():m_major(0),
@@ -466,6 +467,10 @@ const char * GLEScontext::getExtensionString() {
return ret; return ret;
} }
const char * GLEScontext::getRendererString() const {
return s_glRenderer.c_str();
}
void GLEScontext::getGlobalLock() { void GLEScontext::getGlobalLock() {
s_lock.lock(); s_lock.lock();
} }

View File

@@ -131,6 +131,7 @@ public:
bool setBufferData(GLenum target,GLsizeiptr size,const GLvoid* data,GLenum usage); bool setBufferData(GLenum target,GLsizeiptr size,const GLvoid* data,GLenum usage);
bool setBufferSubData(GLenum target,GLintptr offset,GLsizeiptr size,const GLvoid* data); bool setBufferSubData(GLenum target,GLintptr offset,GLsizeiptr size,const GLvoid* data);
const char * getExtensionString(); const char * getExtensionString();
const char * getRendererString() const;
void getGlobalLock(); void getGlobalLock();
void releaseGlobalLock(); void releaseGlobalLock();
virtual GLSupport* getCaps(){return &s_glSupport;}; virtual GLSupport* getCaps(){return &s_glSupport;};
@@ -173,6 +174,7 @@ protected:
GLint m_unpackAlignment; GLint m_unpackAlignment;
ArraysMap m_map; ArraysMap m_map;
static std::string* s_glExtensions; static std::string* s_glExtensions;
static std::string s_glRenderer;
static GLSupport s_glSupport; static GLSupport s_glSupport;
private: private:

View File

@@ -113,8 +113,21 @@ ColorBuffer::ColorBuffer() :
m_tex(0), m_tex(0),
m_eglImage(NULL), m_eglImage(NULL),
m_fbo(0), m_fbo(0),
m_internalFormat(0) m_internalFormat(0),
m_warYInvertBug(false)
{ {
#if __APPLE__
// On Macs running OS X 10.6 and 10.7 with Intel HD Graphics 3000, some
// screens or parts of the screen are displayed upside down. The exact
// conditions/sequence that triggers this aren't known yet; I haven't
// been able to reproduce it in a standalone test. This way of enabling the
// workaround will break if it is a driver bug (rather than a bug in this
// code which works by accident elsewhere) and Apple/Intel release a fix for
// it. Running a standalone test to detect the problem at runtime would be
// more robust.
if (strstr((const char*)s_gl.glGetString(GL_RENDERER), "Intel HD Graphics 3000"))
m_warYInvertBug = true;
#endif
} }
ColorBuffer::~ColorBuffer() ColorBuffer::~ColorBuffer()
@@ -199,7 +212,7 @@ bool ColorBuffer::blitFromCurrentReadBuffer()
s_gl.glBindTexture(GL_TEXTURE_2D, m_blitTex); s_gl.glBindTexture(GL_TEXTURE_2D, m_blitTex);
s_gl.glEnable(GL_TEXTURE_2D); s_gl.glEnable(GL_TEXTURE_2D);
s_gl.glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); s_gl.glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
drawTexQuad(); // this will render the texture flipped drawTexQuad(!m_warYInvertBug);
// unbind the fbo // unbind the fbo
s_gl.glBindFramebufferOES(GL_FRAMEBUFFER_OES, 0); s_gl.glBindFramebufferOES(GL_FRAMEBUFFER_OES, 0);
@@ -299,12 +312,12 @@ bool ColorBuffer::post()
s_gl.glBindTexture(GL_TEXTURE_2D, m_tex); s_gl.glBindTexture(GL_TEXTURE_2D, m_tex);
s_gl.glEnable(GL_TEXTURE_2D); s_gl.glEnable(GL_TEXTURE_2D);
s_gl.glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); s_gl.glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
drawTexQuad(); drawTexQuad(true);
return true; return true;
} }
void ColorBuffer::drawTexQuad() void ColorBuffer::drawTexQuad(bool flipy)
{ {
GLfloat verts[] = { -1.0f, -1.0f, 0.0f, GLfloat verts[] = { -1.0f, -1.0f, 0.0f,
-1.0f, +1.0f, 0.0f, -1.0f, +1.0f, 0.0f,
@@ -316,6 +329,13 @@ void ColorBuffer::drawTexQuad()
1.0f, 1.0f, 1.0f, 1.0f,
1.0f, 0.0f }; 1.0f, 0.0f };
if (!flipy) {
for (int i = 0; i < 4; i++) {
// swap 0.0/1.0 in second element of each tcoord vector
tcoords[2*i + 1] = tcoords[2*i + 1] == 0.0f ? 1.0f : 0.0f;
}
}
s_gl.glClientActiveTexture(GL_TEXTURE0); s_gl.glClientActiveTexture(GL_TEXTURE0);
s_gl.glEnableClientState(GL_TEXTURE_COORD_ARRAY); s_gl.glEnableClientState(GL_TEXTURE_COORD_ARRAY);
s_gl.glTexCoordPointer(2, GL_FLOAT, 0, tcoords); s_gl.glTexCoordPointer(2, GL_FLOAT, 0, tcoords);

View File

@@ -40,7 +40,7 @@ public:
private: private:
ColorBuffer(); ColorBuffer();
void drawTexQuad(); void drawTexQuad(bool flipy);
bool bind_fbo(); // binds a fbo which have this texture as render target bool bind_fbo(); // binds a fbo which have this texture as render target
private: private:
@@ -52,6 +52,7 @@ private:
GLuint m_height; GLuint m_height;
GLuint m_fbo; GLuint m_fbo;
GLenum m_internalFormat; GLenum m_internalFormat;
bool m_warYInvertBug;
}; };
typedef SmartPtr<ColorBuffer> ColorBufferPtr; typedef SmartPtr<ColorBuffer> ColorBufferPtr;