Bug 1060085 - Add entrypoints, use NV_fence in ANGLE ShSurfs. - r=kamidphish
authorJeff Gilbert <jgilbert@mozilla.com>
Tue, 02 Sep 2014 15:15:41 -0700
changeset 203280 d1bc9a5c17ffa24e12bba028a6e17d0936637a50
parent 203279 c4cb0bd2dbf13f48726a17532e24793a8bf8d0f8
child 203281 9d4fc9f2d5d177b10bc0426b5f21a3fa4fae3d5c
push id27425
push userryanvm@gmail.com
push dateWed, 03 Sep 2014 20:38:59 +0000
treeherdermozilla-central@acbdce59da2f [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerskamidphish
bugs1060085
milestone35.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 1060085 - Add entrypoints, use NV_fence in ANGLE ShSurfs. - r=kamidphish
gfx/gl/SharedSurface.cpp
gfx/gl/SharedSurface.h
gfx/gl/SharedSurfaceANGLE.cpp
gfx/gl/SharedSurfaceANGLE.h
--- a/gfx/gl/SharedSurface.cpp
+++ b/gfx/gl/SharedSurface.cpp
@@ -1,17 +1,18 @@
 /* -*- Mode: c++; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40; -*- */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "SharedSurface.h"
 
+#include "GLBlitHelper.h"
 #include "GLContext.h"
-#include "GLBlitHelper.h"
+#include "nsThreadUtils.h"
 #include "ScopedGLHelpers.h"
 #include "SharedSurfaceGL.h"
 
 namespace mozilla {
 namespace gl {
 
 /*static*/ void
 SharedSurface::ProdCopy(SharedSurface* src, SharedSurface* dest,
@@ -190,16 +191,34 @@ SharedSurface::ProdCopy(SharedSurface* s
     }
 
     MOZ_CRASH("Unhandled src->mAttachType.");
 }
 
 ////////////////////////////////////////////////////////////////////////
 // SharedSurface
 
+
+SharedSurface::SharedSurface(SharedSurfaceType type,
+                             AttachmentType attachType,
+                             GLContext* gl,
+                             const gfx::IntSize& size,
+                             bool hasAlpha)
+    : mType(type)
+    , mAttachType(attachType)
+    , mGL(gl)
+    , mSize(size)
+    , mHasAlpha(hasAlpha)
+    , mIsLocked(false)
+#ifdef DEBUG
+    , mOwningThread(NS_GetCurrentThread())
+#endif
+{
+}
+
 void
 SharedSurface::LockProd()
 {
     MOZ_ASSERT(!mIsLocked);
 
     LockProdImpl();
 
     mGL->LockSurface(this);
@@ -213,16 +232,39 @@ SharedSurface::UnlockProd()
         return;
 
     UnlockProdImpl();
 
     mGL->UnlockSurface(this);
     mIsLocked = false;
 }
 
+void
+SharedSurface::Fence_ContentThread()
+{
+    MOZ_ASSERT(NS_GetCurrentThread() == mOwningThread);
+    Fence_ContentThread_Impl();
+}
+
+bool
+SharedSurface::WaitSync_ContentThread()
+{
+    MOZ_ASSERT(NS_GetCurrentThread() == mOwningThread);
+    return WaitSync_ContentThread_Impl();
+}
+
+bool
+SharedSurface::PollSync_ContentThread()
+{
+    MOZ_ASSERT(NS_GetCurrentThread() == mOwningThread);
+    return PollSync_ContentThread_Impl();
+}
+
+
+
 ////////////////////////////////////////////////////////////////////////
 // SurfaceFactory
 
 static void
 ChooseBufferBits(const SurfaceCaps& caps,
                  SurfaceCaps* const out_drawCaps,
                  SurfaceCaps* const out_readCaps)
 {
--- a/gfx/gl/SharedSurface.h
+++ b/gfx/gl/SharedSurface.h
@@ -16,21 +16,24 @@
 #define SHARED_SURFACE_H_
 
 #include <queue>
 #include <stdint.h>
 
 #include "GLContextTypes.h"
 #include "GLDefs.h"
 #include "mozilla/Attributes.h"
+#include "mozilla/DebugOnly.h"
 #include "mozilla/gfx/Point.h"
 #include "mozilla/UniquePtr.h"
 #include "mozilla/WeakPtr.h"
 #include "SurfaceTypes.h"
 
+class nsIThread;
+
 namespace mozilla {
 namespace gl {
 
 class GLContext;
 class SurfaceFactory;
 
 class SharedSurface
 {
@@ -40,30 +43,23 @@ public:
 
     const SharedSurfaceType mType;
     const AttachmentType mAttachType;
     GLContext* const mGL;
     const gfx::IntSize mSize;
     const bool mHasAlpha;
 protected:
     bool mIsLocked;
+    DebugOnly<nsIThread* const> mOwningThread;
 
     SharedSurface(SharedSurfaceType type,
                   AttachmentType attachType,
                   GLContext* gl,
                   const gfx::IntSize& size,
-                  bool hasAlpha)
-        : mType(type)
-        , mAttachType(attachType)
-        , mGL(gl)
-        , mSize(size)
-        , mHasAlpha(hasAlpha)
-        , mIsLocked(false)
-    {
-    }
+                  bool hasAlpha);
 
 public:
     virtual ~SharedSurface() {
     }
 
     bool IsLocked() const {
         return mIsLocked;
     }
@@ -79,16 +75,34 @@ protected:
     virtual void LockProdImpl() = 0;
     virtual void UnlockProdImpl() = 0;
 
 public:
     virtual void Fence() = 0;
     virtual bool WaitSync() = 0;
     virtual bool PollSync() = 0;
 
+    // Use these if you can. They can only be called from the Content
+    // thread, though!
+    void Fence_ContentThread();
+    bool WaitSync_ContentThread();
+    bool PollSync_ContentThread();
+
+protected:
+    virtual void Fence_ContentThread_Impl() {
+        Fence();
+    }
+    virtual bool WaitSync_ContentThread_Impl() {
+        return WaitSync();
+    }
+    virtual bool PollSync_ContentThread_Impl() {
+        return PollSync();
+    }
+
+public:
     // 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 {
         MOZ_ASSERT(mAttachType == AttachmentType::GLTexture);
--- a/gfx/gl/SharedSurfaceANGLE.cpp
+++ b/gfx/gl/SharedSurfaceANGLE.cpp
@@ -12,20 +12,46 @@ namespace mozilla {
 namespace gl {
 
 EGLDisplay
 SharedSurface_ANGLEShareHandle::Display()
 {
     return mEGL->Display();
 }
 
+SharedSurface_ANGLEShareHandle::SharedSurface_ANGLEShareHandle(GLContext* gl,
+                                                               GLLibraryEGL* egl,
+                                                               const gfx::IntSize& size,
+                                                               bool hasAlpha,
+                                                               EGLContext context,
+                                                               EGLSurface pbuffer,
+                                                               HANDLE shareHandle,
+                                                               GLuint fence)
+    : SharedSurface(SharedSurfaceType::EGLSurfaceANGLE,
+                    AttachmentType::Screen,
+                    gl,
+                    size,
+                    hasAlpha)
+    , mEGL(egl)
+    , mContext(context)
+    , mPBuffer(pbuffer)
+    , mShareHandle(shareHandle)
+    , mFence(fence)
+{
+}
+
 
 SharedSurface_ANGLEShareHandle::~SharedSurface_ANGLEShareHandle()
 {
     mEGL->fDestroySurface(Display(), mPBuffer);
+
+    if (mFence) {
+        mGL->MakeCurrent();
+        mGL->fDeleteFences(1, &mFence);
+    }
 }
 
 void
 SharedSurface_ANGLEShareHandle::LockProdImpl()
 {
     GLContextEGL::Cast(mGL)->SetEGLSurfaceOverride(mPBuffer);
 }
 
@@ -35,16 +61,64 @@ SharedSurface_ANGLEShareHandle::UnlockPr
 }
 
 void
 SharedSurface_ANGLEShareHandle::Fence()
 {
     mGL->fFinish();
 }
 
+bool
+SharedSurface_ANGLEShareHandle::WaitSync()
+{
+    return true;
+}
+
+bool
+SharedSurface_ANGLEShareHandle::PollSync()
+{
+    return true;
+}
+
+void
+SharedSurface_ANGLEShareHandle::Fence_ContentThread_Impl()
+{
+    if (mFence) {
+        MOZ_ASSERT(mGL->IsExtensionSupported(GLContext::NV_fence));
+        mGL->fSetFence(mFence, LOCAL_GL_ALL_COMPLETED_NV);
+        mGL->fFlush();
+        return;
+    }
+
+    Fence();
+}
+
+bool
+SharedSurface_ANGLEShareHandle::WaitSync_ContentThread_Impl()
+{
+    if (mFence) {
+        mGL->MakeCurrent();
+        mGL->fFinishFence(mFence);
+        return true;
+    }
+
+    return WaitSync();
+}
+
+bool
+SharedSurface_ANGLEShareHandle::PollSync_ContentThread_Impl()
+{
+    if (mFence) {
+        mGL->MakeCurrent();
+        return mGL->fTestFence(mFence);
+    }
+
+    return PollSync();
+}
+
 static void
 FillPBufferAttribs_ByBits(nsTArray<EGLint>& aAttrs,
                           int redBits, int greenBits,
                           int blueBits, int alphaBits,
                           int depthBits, int stencilBits)
 {
     aAttrs.Clear();
 
@@ -194,19 +268,25 @@ SharedSurface_ANGLEShareHandle::Create(G
                                              pbuffer,
                                              LOCAL_EGL_D3D_TEXTURE_2D_SHARE_HANDLE_ANGLE,
                                              &shareHandle);
     if (!ok) {
         egl->fDestroySurface(egl->Display(), pbuffer);
         return nullptr;
     }
 
+    GLuint fence = 0;
+    if (gl->IsExtensionSupported(GLContext::NV_fence)) {
+        gl->MakeCurrent();
+        gl->fGenFences(1, &fence);
+    }
+
     typedef SharedSurface_ANGLEShareHandle ptrT;
     UniquePtr<ptrT> ret( new ptrT(gl, egl, size, hasAlpha, context,
-                                  pbuffer, shareHandle) );
+                                  pbuffer, shareHandle, fence) );
     return Move(ret);
 }
 
 /*static*/ UniquePtr<SurfaceFactory_ANGLEShareHandle>
 SurfaceFactory_ANGLEShareHandle::Create(GLContext* gl,
                                         const SurfaceCaps& caps)
 {
     GLLibraryEGL* egl = &sEGLLibrary;
--- a/gfx/gl/SharedSurfaceANGLE.h
+++ b/gfx/gl/SharedSurfaceANGLE.h
@@ -32,46 +32,42 @@ public:
         return (SharedSurface_ANGLEShareHandle*)surf;
     }
 
 protected:
     GLLibraryEGL* const mEGL;
     const EGLContext mContext;
     const EGLSurface mPBuffer;
     const HANDLE mShareHandle;
+    const GLuint mFence;
 
     SharedSurface_ANGLEShareHandle(GLContext* gl,
                                    GLLibraryEGL* egl,
                                    const gfx::IntSize& size,
                                    bool hasAlpha,
                                    EGLContext context,
                                    EGLSurface pbuffer,
-                                   HANDLE shareHandle)
-        : SharedSurface(SharedSurfaceType::EGLSurfaceANGLE,
-                        AttachmentType::Screen,
-                        gl,
-                        size,
-                        hasAlpha)
-        , mEGL(egl)
-        , mContext(context)
-        , mPBuffer(pbuffer)
-        , mShareHandle(shareHandle)
-    {}
+                                   HANDLE shareHandle,
+                                   GLuint fence);
 
     EGLDisplay Display();
 
 public:
     virtual ~SharedSurface_ANGLEShareHandle();
 
     virtual void LockProdImpl() MOZ_OVERRIDE;
     virtual void UnlockProdImpl() MOZ_OVERRIDE;
 
     virtual void Fence() MOZ_OVERRIDE;
-    virtual bool WaitSync() MOZ_OVERRIDE { return true; } // Fence is glFinish.
-    virtual bool PollSync() MOZ_OVERRIDE { return true; }
+    virtual bool WaitSync() MOZ_OVERRIDE;
+    virtual bool PollSync() MOZ_OVERRIDE;
+
+    virtual void Fence_ContentThread_Impl() MOZ_OVERRIDE;
+    virtual bool WaitSync_ContentThread_Impl() MOZ_OVERRIDE;
+    virtual bool PollSync_ContentThread_Impl() MOZ_OVERRIDE;
 
     // Implementation-specific functions below:
     HANDLE GetShareHandle() {
         return mShareHandle;
     }
 };