Bug 956993 - Rely on OES_EGL_image_external for SharedSurface_EGLImage r=jgilbert
☠☠ backed out by 416792ed8ef5 ☠ ☠
authorJames Willcox <snorp@snorp.net>
Thu, 27 Feb 2014 20:48:38 -0600
changeset 171472 d0b4c5c28fb0c42fd13cb91a6fce284b8ef169e1
parent 171471 e6e0582268ff5958335ae4eb9915f2d11687a258
child 171473 9b295844b85b57a2141491cf26f516a4e2e55e86
push id270
push userpvanderbeken@mozilla.com
push dateThu, 06 Mar 2014 09:24:21 +0000
reviewersjgilbert
bugs956993
milestone30.0a1
Bug 956993 - Rely on OES_EGL_image_external for SharedSurface_EGLImage r=jgilbert
gfx/gl/ScopedGLHelpers.cpp
gfx/gl/SharedSurfaceEGL.cpp
gfx/gl/SharedSurfaceEGL.h
gfx/layers/opengl/TextureHostOGL.cpp
--- a/gfx/gl/ScopedGLHelpers.cpp
+++ b/gfx/gl/ScopedGLHelpers.cpp
@@ -119,16 +119,17 @@ ScopedTexture::UnwrapImpl()
 void
 ScopedBindTexture::Init(GLenum aTarget)
 {
     mTarget = aTarget;
     mOldTex = 0;
     GLenum bindingTarget = (aTarget == LOCAL_GL_TEXTURE_2D) ? LOCAL_GL_TEXTURE_BINDING_2D
                          : (aTarget == LOCAL_GL_TEXTURE_RECTANGLE_ARB) ? LOCAL_GL_TEXTURE_BINDING_RECTANGLE_ARB
                          : (aTarget == LOCAL_GL_TEXTURE_CUBE_MAP) ? LOCAL_GL_TEXTURE_BINDING_CUBE_MAP
+                         : (aTarget == LOCAL_GL_TEXTURE_EXTERNAL) ? LOCAL_GL_TEXTURE_EXTERNAL
                          : LOCAL_GL_NONE;
     MOZ_ASSERT(bindingTarget != LOCAL_GL_NONE);
     mGL->GetUIntegerv(bindingTarget, &mOldTex);
 }
 
 ScopedBindTexture::ScopedBindTexture(GLContext* aGL, GLuint aNewTex, GLenum aTarget)
         : ScopedGLWrapper<ScopedBindTexture>(aGL)
     {
--- a/gfx/gl/SharedSurfaceEGL.cpp
+++ b/gfx/gl/SharedSurfaceEGL.cpp
@@ -22,180 +22,102 @@ SharedSurface_EGLImage*
 SharedSurface_EGLImage::Create(GLContext* prodGL,
                                const GLFormats& formats,
                                const gfx::IntSize& size,
                                bool hasAlpha,
                                EGLContext context)
 {
     GLLibraryEGL* egl = &sEGLLibrary;
     MOZ_ASSERT(egl);
+    MOZ_ASSERT(context);
 
-    if (!HasExtensions(egl, prodGL))
+    if (!HasExtensions(egl, prodGL)) {
         return nullptr;
+    }
 
     MOZ_ALWAYS_TRUE(prodGL->MakeCurrent());
     GLuint prodTex = CreateTextureForOffscreen(prodGL, formats, size);
-    if (!prodTex)
+    if (!prodTex) {
         return nullptr;
+    }
+
+    EGLClientBuffer buffer = reinterpret_cast<EGLClientBuffer>(prodTex);
+    EGLImage image = egl->fCreateImage(egl->Display(), context,
+                                       LOCAL_EGL_GL_TEXTURE_2D, buffer,
+                                       nullptr);
+    if (!image) {
+        prodGL->fDeleteTextures(1, &prodTex);
+        return nullptr;
+    }
 
     return new SharedSurface_EGLImage(prodGL, egl,
                                       size, hasAlpha,
-                                      formats, prodTex);
+                                      formats, prodTex, image);
 }
 
 
 bool
 SharedSurface_EGLImage::HasExtensions(GLLibraryEGL* egl, GLContext* gl)
 {
     return egl->HasKHRImageBase() &&
            egl->IsExtensionSupported(GLLibraryEGL::KHR_gl_texture_2D_image) &&
-           gl->IsExtensionSupported(GLContext::OES_EGL_image);
+           gl->IsExtensionSupported(GLContext::OES_EGL_image_external);
 }
 
 SharedSurface_EGLImage::SharedSurface_EGLImage(GLContext* gl,
                                                GLLibraryEGL* egl,
                                                const gfx::IntSize& size,
                                                bool hasAlpha,
                                                const GLFormats& formats,
-                                               GLuint prodTex)
+                                               GLuint prodTex,
+                                               EGLImage image)
     : SharedSurface_GL(SharedSurfaceType::EGLImageShare,
                         AttachmentType::GLTexture,
                         gl,
                         size,
                         hasAlpha)
     , mMutex("SharedSurface_EGLImage mutex")
     , mEGL(egl)
     , mFormats(formats)
     , mProdTex(prodTex)
-    , mProdTexForPipe(0)
-    , mImage(0)
+    , mImage(image)
     , mCurConsGL(nullptr)
     , mConsTex(0)
     , mSync(0)
-    , mPipeFailed(false)
-    , mPipeComplete(false)
-    , mPipeActive(false)
 {}
 
 SharedSurface_EGLImage::~SharedSurface_EGLImage()
 {
     mEGL->fDestroyImage(Display(), mImage);
     mImage = 0;
 
     mGL->MakeCurrent();
     mGL->fDeleteTextures(1, &mProdTex);
     mProdTex = 0;
 
-    if (mProdTexForPipe) {
-        mGL->fDeleteTextures(1, &mProdTexForPipe);
-        mProdTexForPipe = 0;
-    }
-
     if (mConsTex) {
         MOZ_ASSERT(mGarbageBin);
         mGarbageBin->Trash(mConsTex);
         mConsTex = 0;
     }
 
     if (mSync) {
         // We can't call this unless we have the ext, but we will always have
         // the ext if we have something to destroy.
         mEGL->fDestroySync(Display(), mSync);
         mSync = 0;
     }
 }
 
 void
-SharedSurface_EGLImage::LockProdImpl()
-{
-    MutexAutoLock lock(mMutex);
-
-    if (!mPipeComplete)
-        return;
-
-    if (mPipeActive)
-        return;
-
-    mGL->BlitHelper()->BlitTextureToTexture(mProdTex, mProdTexForPipe, Size(), Size());
-    mGL->fDeleteTextures(1, &mProdTex);
-    mProdTex = mProdTexForPipe;
-    mProdTexForPipe = 0;
-    mPipeActive = true;
-}
-
-static bool
-CreateTexturePipe(GLLibraryEGL* const egl, GLContext* const gl,
-                  const GLFormats& formats, const gfx::IntSize& size,
-                  GLuint* const out_tex, EGLImage* const out_image)
-{
-    MOZ_ASSERT(out_tex && out_image);
-    *out_tex = 0;
-    *out_image = 0;
-
-    GLuint tex = CreateTextureForOffscreen(gl, formats, size);
-    if (!tex)
-        return false;
-
-    EGLContext context = GLContextEGL::Cast(gl)->GetEGLContext();
-    MOZ_ASSERT(context);
-    EGLClientBuffer buffer = reinterpret_cast<EGLClientBuffer>(tex);
-    EGLImage image = egl->fCreateImage(egl->Display(), context,
-                                       LOCAL_EGL_GL_TEXTURE_2D, buffer,
-                                       nullptr);
-    if (!image) {
-        gl->fDeleteTextures(1, &tex);
-        return false;
-    }
-
-    // Success.
-    *out_tex = tex;
-    *out_image = image;
-    return true;
-}
-
-void
 SharedSurface_EGLImage::Fence()
 {
     MutexAutoLock lock(mMutex);
     mGL->MakeCurrent();
 
-    if (!mPipeActive) {
-        MOZ_ASSERT(!mSync);
-        MOZ_ASSERT(!mPipeComplete);
-
-        if (!mPipeFailed) {
-            if (!CreateTexturePipe(mEGL, mGL, mFormats, Size(),
-                                   &mProdTexForPipe, &mImage))
-            {
-                mPipeFailed = true;
-            }
-        }
-
-        if (!mPixels) {
-            SurfaceFormat format =
-                  HasAlpha() ? SurfaceFormat::B8G8R8A8
-                             : SurfaceFormat::B8G8R8X8;
-            mPixels = Factory::CreateDataSourceSurface(Size(), format);
-        }
-
-        DataSourceSurface::MappedSurface map;
-        mPixels->Map(DataSourceSurface::MapType::WRITE, &map);
-
-        nsRefPtr<gfxImageSurface> wrappedData =
-            new gfxImageSurface(map.mData,
-                                ThebesIntSize(mPixels->GetSize()),
-                                map.mStride,
-                                SurfaceFormatToImageFormat(mPixels->GetFormat()));
-        ReadScreenIntoImageSurface(mGL, wrappedData);
-        mPixels->Unmap();
-        return;
-    }
-    MOZ_ASSERT(mPipeActive);
-    MOZ_ASSERT(mCurConsGL);
-
     if (mEGL->IsExtensionSupported(GLLibraryEGL::KHR_fence_sync) &&
         mGL->IsExtensionSupported(GLContext::OES_EGL_sync))
     {
         if (mSync) {
             MOZ_ALWAYS_TRUE( mEGL->fDestroySync(Display(), mSync) );
             mSync = 0;
         }
 
@@ -244,52 +166,38 @@ SharedSurface_EGLImage::WaitSync()
 
 
 EGLDisplay
 SharedSurface_EGLImage::Display() const
 {
     return mEGL->Display();
 }
 
-GLuint
-SharedSurface_EGLImage::AcquireConsumerTexture(GLContext* consGL)
+void
+SharedSurface_EGLImage::AcquireConsumerTexture(GLContext* consGL, GLuint* out_texture, GLuint* out_target)
 {
     MutexAutoLock lock(mMutex);
     MOZ_ASSERT(!mCurConsGL || consGL == mCurConsGL);
-    if (mPipeFailed)
-        return 0;
-
-    if (mPipeActive) {
-        MOZ_ASSERT(mConsTex);
-
-        return mConsTex;
-    }
 
     if (!mConsTex) {
         consGL->fGenTextures(1, &mConsTex);
-        ScopedBindTexture autoTex(consGL, mConsTex);
-        consGL->fEGLImageTargetTexture2D(LOCAL_GL_TEXTURE_2D, mImage);
+        MOZ_ASSERT(mConsTex);
 
-        mPipeComplete = true;
+        ScopedBindTexture autoTex(consGL, mConsTex, LOCAL_GL_TEXTURE_EXTERNAL);
+        consGL->fEGLImageTargetTexture2D(LOCAL_GL_TEXTURE_EXTERNAL, mImage);
+
         mCurConsGL = consGL;
         mGarbageBin = consGL->TexGarbageBin();
     }
 
     MOZ_ASSERT(consGL == mCurConsGL);
-    return 0;
+    *out_texture = mConsTex;
+    *out_target = LOCAL_GL_TEXTURE_EXTERNAL;
 }
 
-DataSourceSurface*
-SharedSurface_EGLImage::GetPixels() const
-{
-    MutexAutoLock lock(mMutex);
-    return mPixels;
-}
-
-
 
 SurfaceFactory_EGLImage*
 SurfaceFactory_EGLImage::Create(GLContext* prodGL,
                                         const SurfaceCaps& caps)
 {
     EGLContext context = GLContextEGL::Cast(prodGL)->GetEGLContext();
 
     return new SurfaceFactory_EGLImage(prodGL, context, caps);
--- a/gfx/gl/SharedSurfaceEGL.h
+++ b/gfx/gl/SharedSurfaceEGL.h
@@ -35,59 +35,52 @@ public:
         return (SharedSurface_EGLImage*)surf;
     }
 
 protected:
     mutable Mutex mMutex;
     GLLibraryEGL* const mEGL;
     const GLFormats mFormats;
     GLuint mProdTex;
-    RefPtr<gfx::DataSourceSurface> mPixels;
-    GLuint mProdTexForPipe; // Moves to mProdTex when mPipeActive becomes true.
     EGLImage mImage;
     GLContext* mCurConsGL;
     GLuint mConsTex;
     nsRefPtr<TextureGarbageBin> mGarbageBin;
     EGLSync mSync;
-    bool mPipeFailed;   // Pipe creation failed, and has been abandoned.
-    bool mPipeComplete; // Pipe connects (mPipeActive ? mProdTex : mProdTexForPipe) to mConsTex.
-    bool mPipeActive;   // Pipe is complete and in use for production.
 
     SharedSurface_EGLImage(GLContext* gl,
                            GLLibraryEGL* egl,
                            const gfx::IntSize& size,
                            bool hasAlpha,
                            const GLFormats& formats,
-                           GLuint prodTex);
+                           GLuint prodTex,
+                           EGLImage image);
 
     EGLDisplay Display() const;
 
     static bool HasExtensions(GLLibraryEGL* egl, GLContext* gl);
 
 public:
     virtual ~SharedSurface_EGLImage();
 
-    virtual void LockProdImpl();
+    virtual void LockProdImpl() {}
     virtual void UnlockProdImpl() {}
 
 
     virtual void Fence();
     virtual bool WaitSync();
 
 
     virtual GLuint Texture() const {
         return mProdTex;
     }
 
     // Implementation-specific functions below:
-    // Returns 0 if the pipe isn't ready. If 0, use GetPixels below.
-    GLuint AcquireConsumerTexture(GLContext* consGL);
-
-    // Will be void if AcquireConsumerTexture returns non-zero.
-    gfx::DataSourceSurface* GetPixels() const;
+    // Returns texture and target
+    void AcquireConsumerTexture(GLContext* consGL, GLuint* out_texture, GLuint* out_target);
 };
 
 
 
 class SurfaceFactory_EGLImage
     : public SurfaceFactory_GL
 {
 public:
--- a/gfx/layers/opengl/TextureHostOGL.cpp
+++ b/gfx/layers/opengl/TextureHostOGL.cpp
@@ -510,25 +510,20 @@ StreamTextureSourceOGL::RetrieveTextureF
       mFormat = sharedSurf->HasAlpha() ? SurfaceFormat::R8G8B8A8
                                        : SurfaceFormat::R8G8B8X8;
       break;
     }
     case SharedSurfaceType::EGLImageShare: {
       SharedSurface_EGLImage* eglImageSurf =
           SharedSurface_EGLImage::Cast(sharedSurf);
 
-      mTextureHandle = eglImageSurf->AcquireConsumerTexture(gl());
-      mTextureTarget = eglImageSurf->TextureTarget();
-      if (!mTextureHandle) {
-        toUpload = eglImageSurf->GetPixels();
-        MOZ_ASSERT(toUpload);
-      } else {
-        mFormat = sharedSurf->HasAlpha() ? SurfaceFormat::R8G8B8A8
-                                         : SurfaceFormat::R8G8B8X8;
-      }
+      eglImageSurf->AcquireConsumerTexture(gl(), &mTextureHandle, &mTextureTarget);
+      MOZ_ASSERT(mTextureHandle);
+      mFormat = sharedSurf->HasAlpha() ? SurfaceFormat::R8G8B8A8
+                                       : SurfaceFormat::R8G8B8X8;
       break;
     }
 #ifdef XP_MACOSX
     case SharedSurfaceType::IOSurface: {
       SharedSurface_IOSurface* glTexSurf = SharedSurface_IOSurface::Cast(sharedSurf);
       mTextureHandle = glTexSurf->Texture();
       mTextureTarget = glTexSurf->TextureTarget();
       MOZ_ASSERT(mTextureHandle);