Bug 896693 - Work around glCopyTexImage2D errors on framebuffers backed by IOSurface. r=jgilbert

This commit is contained in:
Dan Glastonbury 2015-03-23 13:55:26 +10:00
Родитель 3d60f286ee
Коммит 63a4eb24e5
6 изменённых файлов: 85 добавлений и 2 удалений

Просмотреть файл

@ -1037,8 +1037,16 @@ public:
}
BeforeGLReadCall();
raw_fCopyTexImage2D(target, level, internalformat,
x, y, width, height, border);
bool didCopyTexImage2D = false;
if (mScreen) {
didCopyTexImage2D = mScreen->CopyTexImage2D(target, level, internalformat, x,
y, width, height, border);
}
if (!didCopyTexImage2D) {
raw_fCopyTexImage2D(target, level, internalformat, x, y, width, height,
border);
}
AfterGLReadCall();
}
@ -1932,6 +1940,9 @@ public:
}
private:
friend class SharedSurface_IOSurface;
void raw_fCopyTexImage2D(GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border)
{
BEFORE_GL_CALL;

Просмотреть файл

@ -313,6 +313,23 @@ GLScreenBuffer::BeforeReadCall()
AssureBlitted();
}
bool
GLScreenBuffer::CopyTexImage2D(GLenum target, GLint level, GLenum internalformat, GLint x,
GLint y, GLsizei width, GLsizei height, GLint border)
{
SharedSurface* surf;
if (GetReadFB() == 0) {
surf = SharedSurf();
} else {
surf = mGL->mFBOMapping[GetReadFB()];
}
if (surf) {
return surf->CopyTexImage2D(target, level, internalformat, x, y, width, height, border);
}
return false;
}
bool
GLScreenBuffer::ReadPixels(GLint x, GLint y,
GLsizei width, GLsizei height,

Просмотреть файл

@ -228,6 +228,9 @@ public:
void AfterDrawCall();
void BeforeReadCall();
bool CopyTexImage2D(GLenum target, GLint level, GLenum internalformat, GLint x,
GLint y, GLsizei width, GLsizei height, GLint border);
void SetReadBuffer(GLenum userMode);
/**

Просмотреть файл

@ -156,6 +156,12 @@ public:
MOZ_CRASH("Did you forget to override this function?");
}
virtual bool CopyTexImage2D(GLenum target, GLint level, GLenum internalformat, GLint x,
GLint y, GLsizei width, GLsizei height, GLint border)
{
return false;
}
virtual bool ReadPixels(GLint x, GLint y,
GLsizei width, GLsizei height,
GLenum format, GLenum type,

Просмотреть файл

@ -35,6 +35,49 @@ SharedSurface_IOSurface::Fence()
mGL->fFlush();
}
bool
SharedSurface_IOSurface::CopyTexImage2D(GLenum target, GLint level, GLenum internalformat,
GLint x, GLint y, GLsizei width, GLsizei height,
GLint border)
{
/* Bug 896693 - OpenGL framebuffers that are backed by IOSurface on OSX expose a bug
* in glCopyTexImage2D --- internalformats GL_ALPHA, GL_LUMINANCE, GL_LUMINANCE_ALPHA
* return the wrong results. To work around, copy framebuffer to a temporary texture
* using GL_RGBA (which works), attach as read framebuffer and glCopyTexImage2D
* instead.
*/
// https://www.opengl.org/sdk/docs/man3/xhtml/glCopyTexImage2D.xml says that width or
// height set to 0 results in a NULL texture. Lets not do any work and punt to
// original glCopyTexImage2D, since the FBO below will fail when trying to attach a
// texture of 0 width or height.
if (width == 0 || height == 0)
return false;
MOZ_ASSERT(mGL->IsCurrent());
ScopedTexture destTex(mGL);
{
ScopedBindTexture bindTex(mGL, destTex.Texture());
mGL->fTexParameteri(LOCAL_GL_TEXTURE_2D, LOCAL_GL_TEXTURE_MIN_FILTER,
LOCAL_GL_NEAREST);
mGL->fTexParameteri(LOCAL_GL_TEXTURE_2D, LOCAL_GL_TEXTURE_MAG_FILTER,
LOCAL_GL_NEAREST);
mGL->fTexParameteri(LOCAL_GL_TEXTURE_2D, LOCAL_GL_TEXTURE_WRAP_S,
LOCAL_GL_CLAMP_TO_EDGE);
mGL->fTexParameteri(LOCAL_GL_TEXTURE_2D, LOCAL_GL_TEXTURE_WRAP_T,
LOCAL_GL_CLAMP_TO_EDGE);
mGL->raw_fCopyTexImage2D(LOCAL_GL_TEXTURE_2D, 0, LOCAL_GL_RGBA, x, y, width,
height, 0);
}
ScopedFramebufferForTexture tmpFB(mGL, destTex.Texture(), LOCAL_GL_TEXTURE_2D);
ScopedBindFramebuffer bindFB(mGL, tmpFB.FB());
mGL->raw_fCopyTexImage2D(target, level, internalformat, x, y, width, height, border);
return true;
}
bool
SharedSurface_IOSurface::ReadPixels(GLint x, GLint y, GLsizei width, GLsizei height,
GLenum format, GLenum type, GLvoid* pixels)

Просмотреть файл

@ -30,6 +30,9 @@ public:
virtual bool WaitSync() override { return true; }
virtual bool PollSync() override { return true; }
virtual bool CopyTexImage2D(GLenum target, GLint level, GLenum internalformat,
GLint x, GLint y, GLsizei width, GLsizei height,
GLint border) override;
virtual bool ReadPixels(GLint x, GLint y, GLsizei width, GLsizei height,
GLenum format, GLenum type, GLvoid *pixels) override;