Bug 1066312. Use IDXGIKeyedMutex for synchronization with D3D11 angle. r=jgilbert
authorJeff Muizelaar <jmuizelaar@mozilla.com>
Fri, 31 Oct 2014 10:57:32 -0400
changeset 237722 aede4ed28fd05e30a1fc25c4ad1f440fee935cc1
parent 237721 8cc914e0502e265b8c5cda123f91ba0a25d162a2
child 237723 883218803b63ee5fe0187470acfbfd0b0fe63722
push id4311
push userraliiev@mozilla.com
push dateMon, 12 Jan 2015 19:37:41 +0000
treeherdermozilla-beta@150c9fed433b [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjgilbert
bugs1066312
milestone36.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 1066312. Use IDXGIKeyedMutex for synchronization with D3D11 angle. r=jgilbert This currently does nothing because the ANGLE we're using doesn't have keyed mutex support.
gfx/gl/GLConsts.h
gfx/gl/SharedSurfaceANGLE.cpp
gfx/gl/SharedSurfaceANGLE.h
gfx/layers/composite/TextureHost.cpp
--- a/gfx/gl/GLConsts.h
+++ b/gfx/gl/GLConsts.h
@@ -5182,16 +5182,17 @@
 #define LOCAL_EGL_CONTEXT_PRIORITY_MEDIUM_IMG                0x3102
 #define LOCAL_EGL_CORE_NATIVE_ENGINE                         0x305B
 #define LOCAL_EGL_COVERAGE_BUFFERS_NV                        0x30E0
 #define LOCAL_EGL_COVERAGE_SAMPLES_NV                        0x30E1
 #define LOCAL_EGL_COVERAGE_SAMPLE_RESOLVE_DEFAULT_NV         0x3132
 #define LOCAL_EGL_COVERAGE_SAMPLE_RESOLVE_NONE_NV            0x3133
 #define LOCAL_EGL_COVERAGE_SAMPLE_RESOLVE_NV                 0x3131
 #define LOCAL_EGL_D3D_TEXTURE_2D_SHARE_HANDLE_ANGLE          0x3200
+#define LOCAL_EGL_DXGI_KEYED_MUTEX_ANGLE                     0x3209
 #define LOCAL_EGL_DEFAULT_DISPLAY                            ((EGLNativeDisplayType)0)
 #define LOCAL_EGL_DEPTH_ENCODING_NONE_NV                     0
 #define LOCAL_EGL_DEPTH_ENCODING_NONLINEAR_NV                0x30E3
 #define LOCAL_EGL_DEPTH_ENCODING_NV                          0x30E2
 #define LOCAL_EGL_DEPTH_SIZE                                 0x3025
 #define LOCAL_EGL_DISCARD_SAMPLES_ARM                        0x3286
 #define LOCAL_EGL_DISPLAY_SCALING                            10000
 #define LOCAL_EGL_DMA_BUF_PLANE0_FD_EXT                      0x3272
--- a/gfx/gl/SharedSurfaceANGLE.cpp
+++ b/gfx/gl/SharedSurfaceANGLE.cpp
@@ -1,18 +1,20 @@
 /* -*- 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 "SharedSurfaceANGLE.h"
-
 #include "GLContextEGL.h"
 #include "GLLibraryEGL.h"
 
+#include <d3d11.h>
+#include "gfxWindowsPlatform.h"
+
 namespace mozilla {
 namespace gl {
 
 // Returns `EGL_NO_SURFACE` (`0`) on error.
 static EGLSurface
 CreatePBufferSurface(GLLibraryEGL* egl,
                      EGLDisplay display,
                      EGLConfig config,
@@ -60,52 +62,60 @@ SharedSurface_ANGLEShareHandle::Create(G
     bool ok = egl->fQuerySurfacePointerANGLE(display,
                                              pbuffer,
                                              LOCAL_EGL_D3D_TEXTURE_2D_SHARE_HANDLE_ANGLE,
                                              &shareHandle);
     if (!ok) {
         egl->fDestroySurface(egl->Display(), pbuffer);
         return nullptr;
     }
+    void* opaqueKeyedMutex = nullptr;
+    egl->fQuerySurfacePointerANGLE(display,
+                                   pbuffer,
+                                   LOCAL_EGL_DXGI_KEYED_MUTEX_ANGLE,
+                                   &opaqueKeyedMutex);
+    RefPtr<IDXGIKeyedMutex> keyedMutex = static_cast<IDXGIKeyedMutex*>(opaqueKeyedMutex);
 
     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, fence) );
+                                  pbuffer, shareHandle, keyedMutex, fence) );
     return Move(ret);
 }
 
 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,
+                                                               const RefPtr<IDXGIKeyedMutex>& keyedMutex,
                                                                GLuint fence)
     : SharedSurface(SharedSurfaceType::EGLSurfaceANGLE,
                     AttachmentType::Screen,
                     gl,
                     size,
                     hasAlpha)
     , mEGL(egl)
     , mContext(context)
     , mPBuffer(pbuffer)
     , mShareHandle(shareHandle)
+    , mKeyedMutex(keyedMutex)
     , mFence(fence)
 {
 }
 
 
 SharedSurface_ANGLEShareHandle::~SharedSurface_ANGLEShareHandle()
 {
     mEGL->fDestroySurface(Display(), mPBuffer);
@@ -141,16 +151,68 @@ SharedSurface_ANGLEShareHandle::WaitSync
 
 bool
 SharedSurface_ANGLEShareHandle::PollSync()
 {
     return true;
 }
 
 void
+SharedSurface_ANGLEShareHandle::ProducerAcquireImpl()
+{
+  if (mKeyedMutex)
+      mKeyedMutex->AcquireSync(0, INFINITE);
+}
+
+void
+SharedSurface_ANGLEShareHandle::ProducerReleaseImpl()
+{
+    if (mKeyedMutex) {
+        // XXX: ReleaseSync() has an implicit flush of the D3D commands
+        // whether we need Flush() or not depends on the ANGLE semantics.
+        // For now, we'll just do it
+        mGL->fFlush();
+        mKeyedMutex->ReleaseSync(0);
+        return;
+    }
+    Fence();
+}
+
+void
+SharedSurface_ANGLEShareHandle::ConsumerAcquireImpl()
+{
+    if (!mConsumerTexture) {
+        RefPtr<ID3D11Texture2D> tex;
+        HRESULT hr = gfxWindowsPlatform::GetPlatform()->GetD3D11Device()->OpenSharedResource(mShareHandle,
+                                                                                             __uuidof(ID3D11Texture2D),
+                                                                                             (void**)(ID3D11Texture2D**)byRef(tex));
+        if (SUCCEEDED(hr)) {
+            mConsumerTexture = tex;
+            RefPtr<IDXGIKeyedMutex> mutex;
+            hr = tex->QueryInterface((IDXGIKeyedMutex**)byRef(mutex));
+
+            if (SUCCEEDED(hr)) {
+                mConsumerKeyedMutex = mutex;
+            }
+        }
+    }
+
+    if (mConsumerKeyedMutex)
+        mConsumerKeyedMutex->AcquireSync(0, INFINITE);
+}
+
+void
+SharedSurface_ANGLEShareHandle::ConsumerReleaseImpl()
+{
+    if (mConsumerKeyedMutex) {
+        mConsumerKeyedMutex->ReleaseSync(0);
+    }
+}
+
+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;
     }
--- a/gfx/gl/SharedSurfaceANGLE.h
+++ b/gfx/gl/SharedSurfaceANGLE.h
@@ -2,18 +2,20 @@
 /* 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/. */
 
 #ifndef SHARED_SURFACE_ANGLE_H_
 #define SHARED_SURFACE_ANGLE_H_
 
 #include <windows.h>
+#include "SharedSurface.h"
 
-#include "SharedSurface.h"
+struct IDXGIKeyedMutex;
+struct ID3D11Texture2D;
 
 namespace mozilla {
 namespace gl {
 
 class GLContext;
 class GLLibraryEGL;
 
 class SharedSurface_ANGLEShareHandle
@@ -32,47 +34,60 @@ public:
         return (SharedSurface_ANGLEShareHandle*)surf;
     }
 
 protected:
     GLLibraryEGL* const mEGL;
     const EGLContext mContext;
     const EGLSurface mPBuffer;
     const HANDLE mShareHandle;
+    RefPtr<IDXGIKeyedMutex> mKeyedMutex;
+    RefPtr<IDXGIKeyedMutex> mConsumerKeyedMutex;
+    RefPtr<ID3D11Texture2D> mConsumerTexture;
+
     const GLuint mFence;
 
     SharedSurface_ANGLEShareHandle(GLContext* gl,
                                    GLLibraryEGL* egl,
                                    const gfx::IntSize& size,
                                    bool hasAlpha,
                                    EGLContext context,
                                    EGLSurface pbuffer,
                                    HANDLE shareHandle,
+                                   const RefPtr<IDXGIKeyedMutex>& keyedMutex,
                                    GLuint fence);
 
     EGLDisplay Display();
 
 public:
     virtual ~SharedSurface_ANGLEShareHandle();
 
     virtual void LockProdImpl() MOZ_OVERRIDE;
     virtual void UnlockProdImpl() MOZ_OVERRIDE;
 
     virtual void Fence() MOZ_OVERRIDE;
+    virtual void ProducerAcquireImpl() MOZ_OVERRIDE;
+    virtual void ProducerReleaseImpl() MOZ_OVERRIDE;
+    virtual void ConsumerAcquireImpl() MOZ_OVERRIDE;
+    virtual void ConsumerReleaseImpl() MOZ_OVERRIDE;
     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;
     }
+
+    const RefPtr<ID3D11Texture2D>& GetConsumerTexture() const {
+        return mConsumerTexture;
+    }
 };
 
 
 
 class SurfaceFactory_ANGLEShareHandle
     : public SurfaceFactory
 {
 protected:
--- a/gfx/layers/composite/TextureHost.cpp
+++ b/gfx/layers/composite/TextureHost.cpp
@@ -809,27 +809,22 @@ SharedSurfaceToTexSource(gl::SharedSurfa
   gfx::SurfaceFormat format = abstractSurf->mHasAlpha ? gfx::SurfaceFormat::R8G8B8A8
                                                       : gfx::SurfaceFormat::R8G8B8X8;
 
   RefPtr<TextureSource> texSource;
   switch (abstractSurf->mType) {
 #ifdef XP_WIN
     case gl::SharedSurfaceType::EGLSurfaceANGLE: {
       auto surf = gl::SharedSurface_ANGLEShareHandle::Cast(abstractSurf);
-      HANDLE shareHandle = surf->GetShareHandle();
 
       MOZ_ASSERT(compositor->GetBackendType() == LayersBackend::LAYERS_D3D11);
       CompositorD3D11* compositorD3D11 = static_cast<CompositorD3D11*>(compositor);
-      ID3D11Device* d3d = compositorD3D11->GetDevice();
+      RefPtr<ID3D11Texture2D> tex = surf->GetConsumerTexture();
 
-      nsRefPtr<ID3D11Texture2D> tex;
-      HRESULT hr = d3d->OpenSharedResource(shareHandle,
-                                           __uuidof(ID3D11Texture2D),
-                                           getter_AddRefs(tex));
-      if (FAILED(hr)) {
+      if (!tex) {
         NS_WARNING("Failed to open shared resource.");
         break;
       }
       texSource = new DataTextureSourceD3D11(format, compositorD3D11, tex);
       break;
     }
 #endif
     case gl::SharedSurfaceType::GLTextureShare: {