Bug 1037704 - Add polling support to ShSurf. - r=mattwoodrow
authorJeff Gilbert <jgilbert@mozilla.com>
Mon, 04 Aug 2014 22:10:47 -0700
changeset 197791 4df1d10a90cc460fa1df9837bb507e5b7a31104a
parent 197790 f96a3b13d6e1d95085424dbbbfeb8bd7f892d408
child 197792 9b728101e05f8ec035c63731eec31972ea0d15a2
push id47218
push userjgilbert@mozilla.com
push dateTue, 05 Aug 2014 05:10:38 +0000
treeherdermozilla-inbound@4df1d10a90cc [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmattwoodrow
bugs1037704
milestone34.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1037704 - Add polling support to ShSurf. - r=mattwoodrow
gfx/gl/SharedSurface.h
gfx/gl/SharedSurfaceANGLE.cpp
gfx/gl/SharedSurfaceANGLE.h
gfx/gl/SharedSurfaceEGL.cpp
gfx/gl/SharedSurfaceEGL.h
gfx/gl/SharedSurfaceGL.cpp
gfx/gl/SharedSurfaceGL.h
gfx/gl/SharedSurfaceGralloc.cpp
gfx/gl/SharedSurfaceGralloc.h
gfx/gl/SharedSurfaceIO.h
--- a/gfx/gl/SharedSurface.h
+++ b/gfx/gl/SharedSurface.h
@@ -75,16 +75,17 @@ public:
 
 protected:
     virtual void LockProdImpl() = 0;
     virtual void UnlockProdImpl() = 0;
 
 public:
     virtual void Fence() = 0;
     virtual bool WaitSync() = 0;
+    virtual bool PollSync() = 0;
 
     // This function waits until the buffer is no longer being used.
     // To optimize the performance, some implementaions recycle SharedSurfaces
     // even when its buffer is still being used.
     virtual void WaitForBufferOwnership() {}
 
     // For use when AttachType is correct.
     virtual GLenum ProdTextureTarget() const {
--- a/gfx/gl/SharedSurfaceANGLE.cpp
+++ b/gfx/gl/SharedSurfaceANGLE.cpp
@@ -46,30 +46,22 @@ SharedSurface_ANGLEShareHandle::LockProd
     GLContextEGL::Cast(mGL)->SetEGLSurfaceOverride(mPBuffer);
 }
 
 void
 SharedSurface_ANGLEShareHandle::UnlockProdImpl()
 {
 }
 
-
 void
 SharedSurface_ANGLEShareHandle::Fence()
 {
     mGL->fFinish();
 }
 
-bool
-SharedSurface_ANGLEShareHandle::WaitSync()
-{
-    // Since we glFinish in Fence(), we're always going to be resolved here.
-    return true;
-}
-
 static void
 FillPBufferAttribs_ByBits(nsTArray<EGLint>& aAttrs,
                           int redBits, int greenBits,
                           int blueBits, int alphaBits,
                           int depthBits, int stencilBits)
 {
     aAttrs.Clear();
 
--- a/gfx/gl/SharedSurfaceANGLE.h
+++ b/gfx/gl/SharedSurfaceANGLE.h
@@ -59,17 +59,18 @@ protected:
 
 public:
     virtual ~SharedSurface_ANGLEShareHandle();
 
     virtual void LockProdImpl() MOZ_OVERRIDE;
     virtual void UnlockProdImpl() MOZ_OVERRIDE;
 
     virtual void Fence() MOZ_OVERRIDE;
-    virtual bool WaitSync() MOZ_OVERRIDE;
+    virtual bool WaitSync() MOZ_OVERRIDE { return true; } // Fence is glFinish.
+    virtual bool PollSync() MOZ_OVERRIDE { return true; }
 
     // Implementation-specific functions below:
     HANDLE GetShareHandle() {
         return mShareHandle;
     }
 };
 
 
--- a/gfx/gl/SharedSurfaceEGL.cpp
+++ b/gfx/gl/SharedSurfaceEGL.cpp
@@ -157,16 +157,40 @@ SharedSurface_EGLImage::WaitSync()
     }
 
     MOZ_ALWAYS_TRUE( mEGL->fDestroySync(Display(), mSync) );
     mSync = 0;
 
     return true;
 }
 
+bool
+SharedSurface_EGLImage::PollSync()
+{
+    MutexAutoLock lock(mMutex);
+    if (!mSync) {
+        // We must not be needed.
+        return true;
+    }
+    MOZ_ASSERT(mEGL->IsExtensionSupported(GLLibraryEGL::KHR_fence_sync));
+
+    EGLint status = 0;
+    MOZ_ALWAYS_TRUE( mEGL->fGetSyncAttrib(mEGL->Display(),
+                                         mSync,
+                                         LOCAL_EGL_SYNC_STATUS_KHR,
+                                         &status) );
+    if (status != LOCAL_EGL_SIGNALED_KHR) {
+        return false;
+    }
+
+    MOZ_ALWAYS_TRUE( mEGL->fDestroySync(mEGL->Display(), mSync) );
+    mSync = 0;
+
+    return true;
+}
 
 EGLDisplay
 SharedSurface_EGLImage::Display() const
 {
     return mEGL->Display();
 }
 
 void
--- a/gfx/gl/SharedSurfaceEGL.h
+++ b/gfx/gl/SharedSurfaceEGL.h
@@ -59,19 +59,19 @@ protected:
     void UpdateProdTexture(const MutexAutoLock& curAutoLock);
 
 public:
     virtual ~SharedSurface_EGLImage();
 
     virtual void LockProdImpl() MOZ_OVERRIDE {}
     virtual void UnlockProdImpl() MOZ_OVERRIDE {}
 
-
     virtual void Fence() MOZ_OVERRIDE;
     virtual bool WaitSync() MOZ_OVERRIDE;
+    virtual bool PollSync() MOZ_OVERRIDE;
 
     virtual GLuint ProdTexture() MOZ_OVERRIDE {
       return mProdTex;
     }
 
     // Implementation-specific functions below:
     // Returns texture and target
     void AcquireConsumerTexture(GLContext* consGL, GLuint* out_texture, GLuint* out_target);
--- a/gfx/gl/SharedSurfaceGL.cpp
+++ b/gfx/gl/SharedSurfaceGL.cpp
@@ -164,32 +164,61 @@ SharedSurface_GLTexture::Fence()
     mGL->fFinish();
 }
 
 bool
 SharedSurface_GLTexture::WaitSync()
 {
     MutexAutoLock lock(mMutex);
     if (!mSync) {
-        // We must have used glFinish instead of glFenceSync.
+        // We either used glFinish, or we passed this fence already.
+        // (PollSync/WaitSync returned true previously)
         return true;
     }
 
     mConsGL->MakeCurrent();
     MOZ_ASSERT(mConsGL->IsExtensionSupported(GLContext::ARB_sync));
 
     mConsGL->fWaitSync(mSync,
                        0,
                        LOCAL_GL_TIMEOUT_IGNORED);
     mConsGL->fDeleteSync(mSync);
     mSync = 0;
 
     return true;
 }
 
+bool
+SharedSurface_GLTexture::PollSync()
+{
+    MutexAutoLock lock(mMutex);
+    if (!mSync) {
+        // We either used glFinish, or we passed this fence already.
+        // (PollSync/WaitSync returned true previously)
+        return true;
+    }
+
+    mConsGL->MakeCurrent();
+    MOZ_ASSERT(mConsGL->IsExtensionSupported(GLContext::ARB_sync));
+
+    GLint status = 0;
+    mConsGL->fGetSynciv(mSync,
+                        LOCAL_GL_SYNC_STATUS,
+                        1,
+                        nullptr,
+                        &status);
+    if (status != LOCAL_GL_SIGNALED)
+        return false;
+
+    mConsGL->fDeleteSync(mSync);
+    mSync = 0;
+
+    return true;
+}
+
 GLuint
 SharedSurface_GLTexture::ConsTexture(GLContext* consGL)
 {
     MutexAutoLock lock(mMutex);
     MOZ_ASSERT(consGL);
     MOZ_ASSERT(mGL->SharesWith(consGL));
     MOZ_ASSERT_IF(mConsGL, consGL == mConsGL);
 
--- a/gfx/gl/SharedSurfaceGL.h
+++ b/gfx/gl/SharedSurfaceGL.h
@@ -65,16 +65,17 @@ public:
 
 
     virtual void Fence() MOZ_OVERRIDE;
 
     virtual bool WaitSync() MOZ_OVERRIDE {
         // Since we already store the data in Fence, we're always done already.
         return true;
     }
+    virtual bool PollSync() MOZ_OVERRIDE { return true; }
 
     virtual GLuint ProdTexture() MOZ_OVERRIDE {
         return mTex;
     }
 
     // Implementation-specific functions below:
     gfx::DataSourceSurface* GetData() {
         return mData;
@@ -141,20 +142,19 @@ protected:
     }
 
 public:
     virtual ~SharedSurface_GLTexture();
 
     virtual void LockProdImpl() MOZ_OVERRIDE {}
     virtual void UnlockProdImpl() MOZ_OVERRIDE {}
 
-
     virtual void Fence() MOZ_OVERRIDE;
     virtual bool WaitSync() MOZ_OVERRIDE;
-
+    virtual bool PollSync() MOZ_OVERRIDE;
 
     virtual GLuint ProdTexture() MOZ_OVERRIDE {
         return mTex;
     }
 
     // Custom:
 
     GLuint ConsTexture(GLContext* consGL);
--- a/gfx/gl/SharedSurfaceGralloc.cpp
+++ b/gfx/gl/SharedSurfaceGralloc.cpp
@@ -246,16 +246,40 @@ SharedSurface_Gralloc::WaitSync()
     }
 
     MOZ_ALWAYS_TRUE( mEGL->fDestroySync(mEGL->Display(), mSync) );
     mSync = 0;
 
     return true;
 }
 
+bool
+SharedSurface_Gralloc::PollSync()
+{
+    if (!mSync) {
+        // We must not be needed.
+        return true;
+    }
+    MOZ_ASSERT(mEGL->IsExtensionSupported(GLLibraryEGL::KHR_fence_sync));
+
+    EGLint status = 0;
+    MOZ_ALWAYS_TRUE( mEGL->fGetSyncAttrib(mEGL->Display(),
+                                         mSync,
+                                         LOCAL_EGL_SYNC_STATUS_KHR,
+                                         &status) );
+    if (status != LOCAL_EGL_SIGNALED_KHR) {
+        return false;
+    }
+
+    MOZ_ALWAYS_TRUE( mEGL->fDestroySync(mEGL->Display(), mSync) );
+    mSync = 0;
+
+    return true;
+}
+
 void
 SharedSurface_Gralloc::WaitForBufferOwnership()
 {
     mTextureClient->WaitForBufferOwnership();
 }
 
 }
 }
--- a/gfx/gl/SharedSurfaceGralloc.h
+++ b/gfx/gl/SharedSurfaceGralloc.h
@@ -52,16 +52,17 @@ protected:
 
     static bool HasExtensions(GLLibraryEGL* egl, GLContext* gl);
 
 public:
     virtual ~SharedSurface_Gralloc();
 
     virtual void Fence() MOZ_OVERRIDE;
     virtual bool WaitSync() MOZ_OVERRIDE;
+    virtual bool PollSync() MOZ_OVERRIDE;
 
     virtual void WaitForBufferOwnership() MOZ_OVERRIDE;
 
     virtual void LockProdImpl() MOZ_OVERRIDE {}
     virtual void UnlockProdImpl() MOZ_OVERRIDE {}
 
     virtual GLuint ProdTexture() MOZ_OVERRIDE {
         return mProdTex;
--- a/gfx/gl/SharedSurfaceIO.h
+++ b/gfx/gl/SharedSurfaceIO.h
@@ -21,16 +21,17 @@ public:
 
     ~SharedSurface_IOSurface();
 
     virtual void LockProdImpl() MOZ_OVERRIDE { }
     virtual void UnlockProdImpl() MOZ_OVERRIDE { }
 
     virtual void Fence() MOZ_OVERRIDE;
     virtual bool WaitSync() MOZ_OVERRIDE { return true; }
+    virtual bool PollSync() MOZ_OVERRIDE { return true; }
 
     virtual bool ReadPixels(GLint x, GLint y, GLsizei width, GLsizei height,
                             GLenum format, GLenum type, GLvoid *pixels) MOZ_OVERRIDE;
 
     virtual GLuint ProdTexture() MOZ_OVERRIDE {
         return mProdTex;
     }