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
diff --git a/tools/emulator/opengl/host/libs/Translator/GLES_CM/GLEScmContext.cpp b/tools/emulator/opengl/host/libs/Translator/GLES_CM/GLEScmContext.cpp
index ef60cdc..abf461c 100644
--- a/tools/emulator/opengl/host/libs/Translator/GLES_CM/GLEScmContext.cpp
+++ b/tools/emulator/opengl/host/libs/Translator/GLES_CM/GLEScmContext.cpp
@@ -31,6 +31,13 @@
m_texCoords = new GLESpointer[s_glSupport.maxTexUnits];
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;
}
diff --git a/tools/emulator/opengl/host/libs/Translator/GLES_CM/GLEScmImp.cpp b/tools/emulator/opengl/host/libs/Translator/GLES_CM/GLEScmImp.cpp
index f1d3801..ae90377 100644
--- a/tools/emulator/opengl/host/libs/Translator/GLES_CM/GLEScmImp.cpp
+++ b/tools/emulator/opengl/host/libs/Translator/GLES_CM/GLEScmImp.cpp
@@ -249,15 +249,14 @@
GL_API const GLubyte * GL_APIENTRY glGetString( GLenum name) {
GET_CTX_RET(NULL)
- static GLubyte VENDOR[] = "Google";
- static GLubyte RENDERER[] = "OpenGL ES-CM 1.1";
- static GLubyte VERSION[] = "OpenGL ES-CM 1.1";
+ static const GLubyte VENDOR[] = "Google";
+ static const GLubyte VERSION[] = "OpenGL ES-CM 1.1";
switch(name) {
case GL_VENDOR:
return VENDOR;
case GL_RENDERER:
- return RENDERER;
+ return (const GLubyte*)ctx->getRendererString();
case GL_VERSION:
return VERSION;
case GL_EXTENSIONS:
diff --git a/tools/emulator/opengl/host/libs/Translator/GLES_V2/GLESv2Context.cpp b/tools/emulator/opengl/host/libs/Translator/GLES_V2/GLESv2Context.cpp
index 92f9319..73acb61 100644
--- a/tools/emulator/opengl/host/libs/Translator/GLES_V2/GLESv2Context.cpp
+++ b/tools/emulator/opengl/host/libs/Translator/GLES_V2/GLESv2Context.cpp
@@ -27,6 +27,14 @@
m_map[i] = new GLESpointer();
}
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;
}
diff --git a/tools/emulator/opengl/host/libs/Translator/GLES_V2/GLESv2Imp.cpp b/tools/emulator/opengl/host/libs/Translator/GLES_V2/GLESv2Imp.cpp
index 319930e..2e746cf 100644
--- a/tools/emulator/opengl/host/libs/Translator/GLES_V2/GLESv2Imp.cpp
+++ b/tools/emulator/opengl/host/libs/Translator/GLES_V2/GLESv2Imp.cpp
@@ -1317,15 +1317,14 @@
GL_APICALL const GLubyte* GL_APIENTRY glGetString(GLenum name){
GET_CTX_RET(NULL)
- static GLubyte VENDOR[] = "Google";
- static GLubyte RENDERER[] = "OpenGL ES 2.0";
- static GLubyte VERSION[] = "OpenGL ES 2.0";
- static GLubyte SHADING[] = "OpenGL ES GLSL ES 1.0.17";
+ static const GLubyte VENDOR[] = "Google";
+ static const GLubyte VERSION[] = "OpenGL ES 2.0";
+ static const GLubyte SHADING[] = "OpenGL ES GLSL ES 1.0.17";
switch(name) {
case GL_VENDOR:
return VENDOR;
case GL_RENDERER:
- return RENDERER;
+ return (const GLubyte*)ctx->getRendererString();
case GL_VERSION:
return VERSION;
case GL_SHADING_LANGUAGE_VERSION:
diff --git a/tools/emulator/opengl/host/libs/Translator/GLcommon/GLEScontext.cpp b/tools/emulator/opengl/host/libs/Translator/GLcommon/GLEScontext.cpp
index 90088f3..c213903 100644
--- a/tools/emulator/opengl/host/libs/Translator/GLcommon/GLEScontext.cpp
+++ b/tools/emulator/opengl/host/libs/Translator/GLcommon/GLEScontext.cpp
@@ -71,6 +71,7 @@
GLDispatch GLEScontext::s_glDispatch;
android::Mutex GLEScontext::s_lock;
std::string* GLEScontext::s_glExtensions= NULL;
+std::string GLEScontext::s_glRenderer;
GLSupport GLEScontext::s_glSupport;
Version::Version():m_major(0),
@@ -469,6 +470,10 @@
return ret;
}
+const char * GLEScontext::getRendererString() const {
+ return s_glRenderer.c_str();
+}
+
void GLEScontext::getGlobalLock() {
s_lock.lock();
}
diff --git a/tools/emulator/opengl/host/libs/Translator/include/GLcommon/GLEScontext.h b/tools/emulator/opengl/host/libs/Translator/include/GLcommon/GLEScontext.h
index d266e3d..59e367f 100644
--- a/tools/emulator/opengl/host/libs/Translator/include/GLcommon/GLEScontext.h
+++ b/tools/emulator/opengl/host/libs/Translator/include/GLcommon/GLEScontext.h
@@ -131,6 +131,7 @@
bool setBufferData(GLenum target,GLsizeiptr size,const GLvoid* data,GLenum usage);
bool setBufferSubData(GLenum target,GLintptr offset,GLsizeiptr size,const GLvoid* data);
const char * getExtensionString();
+ const char * getRendererString() const;
void getGlobalLock();
void releaseGlobalLock();
virtual GLSupport* getCaps(){return &s_glSupport;};
@@ -173,6 +174,7 @@
GLint m_unpackAlignment;
ArraysMap m_map;
static std::string* s_glExtensions;
+ static std::string s_glRenderer;
static GLSupport s_glSupport;
private:
diff --git a/tools/emulator/opengl/host/libs/libOpenglRender/ColorBuffer.cpp b/tools/emulator/opengl/host/libs/libOpenglRender/ColorBuffer.cpp
index 87e7a24..218f32b 100644
--- a/tools/emulator/opengl/host/libs/libOpenglRender/ColorBuffer.cpp
+++ b/tools/emulator/opengl/host/libs/libOpenglRender/ColorBuffer.cpp
@@ -113,8 +113,21 @@
m_tex(0),
m_eglImage(NULL),
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()
@@ -199,7 +212,7 @@
s_gl.glBindTexture(GL_TEXTURE_2D, m_blitTex);
s_gl.glEnable(GL_TEXTURE_2D);
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
s_gl.glBindFramebufferOES(GL_FRAMEBUFFER_OES, 0);
@@ -299,12 +312,12 @@
s_gl.glBindTexture(GL_TEXTURE_2D, m_tex);
s_gl.glEnable(GL_TEXTURE_2D);
s_gl.glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
- drawTexQuad();
+ drawTexQuad(true);
return true;
}
-void ColorBuffer::drawTexQuad()
+void ColorBuffer::drawTexQuad(bool flipy)
{
GLfloat verts[] = { -1.0f, -1.0f, 0.0f,
-1.0f, +1.0f, 0.0f,
@@ -316,6 +329,13 @@
1.0f, 1.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.glEnableClientState(GL_TEXTURE_COORD_ARRAY);
s_gl.glTexCoordPointer(2, GL_FLOAT, 0, tcoords);
diff --git a/tools/emulator/opengl/host/libs/libOpenglRender/ColorBuffer.h b/tools/emulator/opengl/host/libs/libOpenglRender/ColorBuffer.h
index 16d1ee9..4a2c6b4 100644
--- a/tools/emulator/opengl/host/libs/libOpenglRender/ColorBuffer.h
+++ b/tools/emulator/opengl/host/libs/libOpenglRender/ColorBuffer.h
@@ -40,7 +40,7 @@
private:
ColorBuffer();
- void drawTexQuad();
+ void drawTexQuad(bool flipy);
bool bind_fbo(); // binds a fbo which have this texture as render target
private:
@@ -52,6 +52,7 @@
GLuint m_height;
GLuint m_fbo;
GLenum m_internalFormat;
+ bool m_warYInvertBug;
};
typedef SmartPtr<ColorBuffer> ColorBufferPtr;