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:
@@ -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;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -249,15 +249,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:
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1317,15 +1317,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:
|
||||||
|
|||||||
@@ -71,6 +71,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),
|
||||||
@@ -469,6 +470,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();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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:
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
Reference in New Issue
Block a user