Bug 980684 - Actually use IOSurfaces on Mac. - r=snorp

This commit is contained in:
Jeff Gilbert 2014-03-10 19:08:50 -07:00
parent 7cf50c98a3
commit 3ba237c70c
6 changed files with 92 additions and 43 deletions

View File

@ -2698,13 +2698,12 @@ protected:
// storage to support DebugMode on an arbitrary thread.
static unsigned sCurrentGLContextTLS;
#endif
ScopedDeletePtr<GLBlitHelper> mBlitHelper;
ScopedDeletePtr<GLBlitTextureImageHelper> mBlitTextureImageHelper;
ScopedDeletePtr<GLReadTexImageHelper> mReadTexImageHelper;
public:
GLBlitHelper* BlitHelper();
GLBlitTextureImageHelper* BlitTextureImageHelper();
GLReadTexImageHelper* ReadTexImageHelper();

View File

@ -407,7 +407,6 @@ SharedSurface_GLTexture::WaitSync()
return true;
}
MOZ_ASSERT(mConsGL, "Did you forget to call a deferred `SetConsumerGL()`?");
mConsGL->MakeCurrent();
MOZ_ASSERT(mConsGL->IsExtensionSupported(GLContext::ARB_sync));
@ -420,13 +419,17 @@ SharedSurface_GLTexture::WaitSync()
return true;
}
void
SharedSurface_GLTexture::SetConsumerGL(GLContext* consGL)
GLuint
SharedSurface_GLTexture::ConsTexture(GLContext* consGL)
{
MutexAutoLock lock(mMutex);
MOZ_ASSERT(consGL);
MOZ_ASSERT(mGL->SharesWith(consGL));
MOZ_ASSERT_IF(mConsGL, consGL == mConsGL);
mConsGL = consGL;
return mTex;
}
} /* namespace gfx */

View File

@ -260,7 +260,12 @@ public:
}
// Custom:
void SetConsumerGL(GLContext* consGL);
GLuint ConsTexture(GLContext* consGL);
GLenum ConsTextureTarget() const {
return ProdTextureTarget();
}
};
class SurfaceFactory_GLTexture

View File

@ -41,57 +41,94 @@ SharedSurface_IOSurface::ReadPixels(GLint x, GLint y, GLsizei width, GLsizei hei
// reading from an IOSurface).
// We workaround this by copying to a temporary texture, and doing the readback
// from that.
ScopedTexture texture(mGL);
ScopedBindTexture bindTex(mGL, texture.Texture());
mGL->fCopyTexImage2D(LOCAL_GL_TEXTURE_2D, 0,
HasAlpha() ? LOCAL_GL_RGBA : LOCAL_GL_RGB,
x, y,
width, height, 0);
MOZ_ASSERT(mGL->IsCurrent());
ScopedFramebufferForTexture fb(mGL, texture.Texture());
ScopedBindFramebuffer bindFB(mGL, fb.FB());
ScopedTexture destTex(mGL);
{
ScopedFramebufferForTexture srcFB(mGL, ProdTexture(), ProdTextureTarget());
ScopedBindFramebuffer bindFB(mGL, srcFB.FB());
ScopedBindTexture bindTex(mGL, destTex.Texture());
mGL->fCopyTexImage2D(LOCAL_GL_TEXTURE_2D, 0,
HasAlpha() ? LOCAL_GL_RGBA : LOCAL_GL_RGB,
x, y,
width, height, 0);
}
ScopedFramebufferForTexture destFB(mGL, destTex.Texture());
ScopedBindFramebuffer bindFB(mGL, destFB.FB());
mGL->fReadPixels(0, 0, width, height, format, type, pixels);
return true;
}
static void
BackTextureWithIOSurf(GLContext* gl, GLuint tex, MacIOSurface* ioSurf)
{
MOZ_ASSERT(gl->IsCurrent());
ScopedBindTexture texture(gl, tex, LOCAL_GL_TEXTURE_RECTANGLE_ARB);
gl->fTexParameteri(LOCAL_GL_TEXTURE_RECTANGLE_ARB,
LOCAL_GL_TEXTURE_MIN_FILTER,
LOCAL_GL_LINEAR);
gl->fTexParameteri(LOCAL_GL_TEXTURE_RECTANGLE_ARB,
LOCAL_GL_TEXTURE_MAG_FILTER,
LOCAL_GL_LINEAR);
gl->fTexParameteri(LOCAL_GL_TEXTURE_RECTANGLE_ARB,
LOCAL_GL_TEXTURE_WRAP_S,
LOCAL_GL_CLAMP_TO_EDGE);
gl->fTexParameteri(LOCAL_GL_TEXTURE_RECTANGLE_ARB,
LOCAL_GL_TEXTURE_WRAP_T,
LOCAL_GL_CLAMP_TO_EDGE);
CGLContextObj cgl = GLContextCGL::Cast(gl)->GetCGLContext();
MOZ_ASSERT(cgl);
ioSurf->CGLTexImageIOSurface2D(cgl);
}
SharedSurface_IOSurface::SharedSurface_IOSurface(MacIOSurface* surface,
GLContext* gl,
const gfx::IntSize& size,
bool hasAlpha)
: SharedSurface_GL(SharedSurfaceType::IOSurface, AttachmentType::GLTexture, gl, size, hasAlpha)
, mSurface(surface)
, mCurConsGL(nullptr)
, mConsTex(0)
{
mGL->MakeCurrent();
mGL->fGenTextures(1, &mTexture);
gl->MakeCurrent();
mProdTex = 0;
gl->fGenTextures(1, &mProdTex);
BackTextureWithIOSurf(gl, mProdTex, surface);
}
ScopedBindTexture texture(mGL, mTexture, LOCAL_GL_TEXTURE_RECTANGLE_ARB);
GLuint
SharedSurface_IOSurface::ConsTexture(GLContext* consGL)
{
if (!mCurConsGL) {
mCurConsGL = consGL;
}
MOZ_ASSERT(consGL == mCurConsGL);
mGL->fTexParameteri(LOCAL_GL_TEXTURE_RECTANGLE_ARB,
LOCAL_GL_TEXTURE_MIN_FILTER,
LOCAL_GL_LINEAR);
mGL->fTexParameteri(LOCAL_GL_TEXTURE_RECTANGLE_ARB,
LOCAL_GL_TEXTURE_MAG_FILTER,
LOCAL_GL_LINEAR);
mGL->fTexParameteri(LOCAL_GL_TEXTURE_RECTANGLE_ARB,
LOCAL_GL_TEXTURE_WRAP_S,
LOCAL_GL_CLAMP_TO_EDGE);
mGL->fTexParameteri(LOCAL_GL_TEXTURE_RECTANGLE_ARB,
LOCAL_GL_TEXTURE_WRAP_T,
LOCAL_GL_CLAMP_TO_EDGE);
if (!mConsTex) {
consGL->MakeCurrent();
mConsTex = 0;
consGL->fGenTextures(1, &mConsTex);
BackTextureWithIOSurf(consGL, mConsTex, mSurface);
}
CGLContextObj ctx = GLContextCGL::Cast(mGL)->GetCGLContext();
MOZ_ASSERT(ctx);
surface->CGLTexImageIOSurface2D(ctx);
return mConsTex;
}
SharedSurface_IOSurface::~SharedSurface_IOSurface()
{
if (mTexture) {
if (mProdTex) {
DebugOnly<bool> success = mGL->MakeCurrent();
MOZ_ASSERT(success);
mGL->fDeleteTextures(1, &mTexture);
mGL->fDeleteTextures(1, &mProdTex);
mGL->fDeleteTextures(1, &mConsTex); // This will work if we're shared.
}
}

View File

@ -31,7 +31,7 @@ public:
GLenum format, GLenum type, GLvoid *pixels) MOZ_OVERRIDE;
virtual GLuint ProdTexture() MOZ_OVERRIDE {
return mTexture;
return mProdTex;
}
virtual GLenum ProdTextureTarget() const MOZ_OVERRIDE {
@ -43,14 +43,20 @@ public:
return static_cast<SharedSurface_IOSurface*>(surf);
}
MacIOSurface* GetIOSurface() { return mSurface; }
GLuint ConsTexture(GLContext* consGL);
GLenum ConsTextureTarget() const {
return LOCAL_GL_TEXTURE_RECTANGLE_ARB;
}
private:
SharedSurface_IOSurface(MacIOSurface* surface, GLContext* gl, const gfx::IntSize& size, bool hasAlpha);
RefPtr<MacIOSurface> mSurface;
nsRefPtr<gfxImageSurface> mImageSurface;
GLuint mTexture;
GLuint mProdTex;
const GLContext* mCurConsGL;
GLuint mConsTex;
};
class SurfaceFactory_IOSurface : public SurfaceFactory_GL

View File

@ -503,9 +503,8 @@ StreamTextureSourceOGL::RetrieveTextureFromStream()
switch (sharedSurf->Type()) {
case SharedSurfaceType::GLTextureShare: {
SharedSurface_GLTexture* glTexSurf = SharedSurface_GLTexture::Cast(sharedSurf);
glTexSurf->SetConsumerGL(gl());
mTextureHandle = glTexSurf->ProdTexture();
mTextureTarget = glTexSurf->ProdTextureTarget();
mTextureHandle = glTexSurf->ConsTexture(gl());
mTextureTarget = glTexSurf->ConsTextureTarget();
MOZ_ASSERT(mTextureHandle);
mFormat = sharedSurf->HasAlpha() ? SurfaceFormat::R8G8B8A8
: SurfaceFormat::R8G8B8X8;
@ -524,8 +523,8 @@ StreamTextureSourceOGL::RetrieveTextureFromStream()
#ifdef XP_MACOSX
case SharedSurfaceType::IOSurface: {
SharedSurface_IOSurface* glTexSurf = SharedSurface_IOSurface::Cast(sharedSurf);
mTextureHandle = glTexSurf->ProdTexture();
mTextureTarget = glTexSurf->ProdTextureTarget();
mTextureHandle = glTexSurf->ConsTexture(gl());
mTextureTarget = glTexSurf->ConsTextureTarget();
MOZ_ASSERT(mTextureHandle);
mFormat = sharedSurf->HasAlpha() ? SurfaceFormat::R8G8B8A8
: SurfaceFormat::R8G8B8X8;