Clean up and relax some assertions in SyncObjectD3D11.cpp. (bug 1319557, r=mattwoodrow)
authorDavid Anderson <danderson@mozilla.com>
Tue, 29 Nov 2016 14:07:27 -0800
changeset 324681 28e269b5ab120e15b7cf22f082befb1ed00cd5d5
parent 324680 a544ec8cb49864b7c8ff2921e47c9b64160ac1e7
child 324682 e10cae7946b2581b3737771d456f4474734c63f7
push id84475
push userdanderson@mozilla.com
push dateTue, 29 Nov 2016 22:17:27 +0000
treeherdermozilla-inbound@28e269b5ab12 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmattwoodrow
bugs1319557
milestone53.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
Clean up and relax some assertions in SyncObjectD3D11.cpp. (bug 1319557, r=mattwoodrow)
gfx/layers/d3d11/TextureD3D11.cpp
gfx/layers/d3d11/TextureD3D11.h
gfx/layers/ipc/CompositorBridgeChild.cpp
gfx/layers/ipc/CompositorBridgeChild.h
--- a/gfx/layers/d3d11/TextureD3D11.cpp
+++ b/gfx/layers/d3d11/TextureD3D11.cpp
@@ -8,16 +8,17 @@
 #include "gfxContext.h"
 #include "Effects.h"
 #include "gfxWindowsPlatform.h"
 #include "gfx2DGlue.h"
 #include "gfxPrefs.h"
 #include "ReadbackManagerD3D11.h"
 #include "mozilla/gfx/DeviceManagerDx.h"
 #include "mozilla/gfx/Logging.h"
+#include "mozilla/layers/CompositorBridgeChild.h"
 
 namespace mozilla {
 
 using namespace gfx;
 
 namespace layers {
 
 static const GUID sD3D11TextureUsage =
@@ -1189,93 +1190,97 @@ CompositingRenderTargetD3D11::BindRender
 }
 
 IntSize
 CompositingRenderTargetD3D11::GetSize() const
 {
   return TextureSourceD3D11::GetSize();
 }
 
-SyncObjectD3D11::SyncObjectD3D11(SyncHandle aHandle)
+SyncObjectD3D11::SyncObjectD3D11(SyncHandle aSyncHandle)
+ : mSyncHandle(aSyncHandle)
+{
+}
+
+bool
+SyncObjectD3D11::Init()
 {
-  MOZ_ASSERT(aHandle);
+  if (mKeyedMutex) {
+    return true;
+  }
+
+  RefPtr<ID3D11Device> device = DeviceManagerDx::Get()->GetContentDevice();
 
-  mHandle = aHandle;
+  HRESULT hr = device->OpenSharedResource(
+    mSyncHandle,
+    __uuidof(ID3D11Texture2D),
+    (void**)(ID3D11Texture2D**)getter_AddRefs(mD3D11Texture));
+  if (FAILED(hr) || !mD3D11Texture) {
+    gfxCriticalNote << "Failed to OpenSharedResource for SyncObjectD3D11: " << hexa(hr);
+    if (!CompositorBridgeChild::CompositorIsInGPUProcess() &&
+        !DeviceManagerDx::Get()->HasDeviceReset())
+    {
+      gfxDevCrash(LogReason::D3D11FinalizeFrame) << "Without device reset: " << hexa(hr);
+    }
+  }
+
+  hr = mD3D11Texture->QueryInterface(__uuidof(IDXGIKeyedMutex), getter_AddRefs(mKeyedMutex));
+  if (FAILED(hr) || !mKeyedMutex) {
+    // Leave both the critical error and MOZ_CRASH for now; the critical error lets
+    // us "save" the hr value.  We will probably eventuall replace this with gfxDevCrash.
+    gfxCriticalError() << "Failed to get KeyedMutex (2): " << hexa(hr);
+    MOZ_CRASH("GFX: Cannot get D3D11 KeyedMutex");
+  }
+
+  return true;
 }
 
 void
 SyncObjectD3D11::RegisterTexture(ID3D11Texture2D* aTexture)
 {
   mD3D11SyncedTextures.push_back(aTexture);
 }
 
 void
 SyncObjectD3D11::FinalizeFrame()
 {
-  HRESULT hr;
-
-  if (!mD3D11Texture && mD3D11SyncedTextures.size()) {
-    RefPtr<ID3D11Device> device = DeviceManagerDx::Get()->GetContentDevice();
-
-    hr = device->OpenSharedResource(mHandle, __uuidof(ID3D11Texture2D), (void**)(ID3D11Texture2D**)getter_AddRefs(mD3D11Texture));
-
-    if (FAILED(hr) || !mD3D11Texture) {
-      gfxCriticalError() << "Failed to D3D11 OpenSharedResource for frame finalization: " << hexa(hr);
-
-      if (DeviceManagerDx::Get()->HasDeviceReset()) {
-        return;
-      }
+  if (!mD3D11SyncedTextures.size()) {
+    return;
+  }
+  if (!Init()) {
+    return;
+  }
 
-      gfxDevCrash(LogReason::D3D11FinalizeFrame) << "Without device reset: " << hexa(hr);
-    }
-
-    // test QI
-    RefPtr<IDXGIKeyedMutex> mutex;
-    hr = mD3D11Texture->QueryInterface((IDXGIKeyedMutex**)getter_AddRefs(mutex));
+  HRESULT hr;
+  AutoTextureLock lock(mKeyedMutex, hr, 20000);
 
-    if (FAILED(hr) || !mutex) {
-      // Leave both the critical error and MOZ_CRASH for now; the critical error lets
-      // us "save" the hr value.  We will probably eventuall replace this with gfxDevCrash.
-      gfxCriticalError() << "Failed to get KeyedMutex (2): " << hexa(hr);
-      MOZ_CRASH("GFX: Cannot get D3D11 KeyedMutex");
+  if (hr == WAIT_TIMEOUT) {
+    if (DeviceManagerDx::Get()->HasDeviceReset()) {
+      gfxWarning() << "AcquireSync timed out because of device reset.";
+      return;
     }
+    gfxDevCrash(LogReason::D3D11SyncLock) << "Timeout on the D3D11 sync lock";
   }
 
-  if (mD3D11SyncedTextures.size()) {
-    RefPtr<IDXGIKeyedMutex> mutex;
-    hr = mD3D11Texture->QueryInterface((IDXGIKeyedMutex**)getter_AddRefs(mutex));
-    {
-      AutoTextureLock lock(mutex, hr, 20000);
-
-      if (hr == WAIT_TIMEOUT) {
-        if (DeviceManagerDx::Get()->HasDeviceReset()) {
-          gfxWarning() << "AcquireSync timed out because of device reset.";
-          return;
-        }
-        gfxDevCrash(LogReason::D3D11SyncLock) << "Timeout on the D3D11 sync lock";
-      }
-
-      D3D11_BOX box;
-      box.front = box.top = box.left = 0;
-      box.back = box.bottom = box.right = 1;
+  D3D11_BOX box;
+  box.front = box.top = box.left = 0;
+  box.back = box.bottom = box.right = 1;
 
-      RefPtr<ID3D11Device> dev = DeviceManagerDx::Get()->GetContentDevice();
-      if (!dev) {
-        if (DeviceManagerDx::Get()->HasDeviceReset()) {
-          return;
-        }
-        MOZ_CRASH("GFX: Invalid D3D11 content device");
-      }
+  RefPtr<ID3D11Device> dev = DeviceManagerDx::Get()->GetContentDevice();
+  if (!dev) {
+    if (DeviceManagerDx::Get()->HasDeviceReset()) {
+      return;
+    }
+    MOZ_CRASH("GFX: Invalid D3D11 content device");
+  }
 
-      RefPtr<ID3D11DeviceContext> ctx;
-      dev->GetImmediateContext(getter_AddRefs(ctx));
+  RefPtr<ID3D11DeviceContext> ctx;
+  dev->GetImmediateContext(getter_AddRefs(ctx));
 
-      for (auto iter = mD3D11SyncedTextures.begin(); iter != mD3D11SyncedTextures.end(); iter++) {
-        ctx->CopySubresourceRegion(mD3D11Texture, 0, 0, 0, 0, *iter, 0, &box);
-      }
-    }
+  for (auto iter = mD3D11SyncedTextures.begin(); iter != mD3D11SyncedTextures.end(); iter++) {
+    ctx->CopySubresourceRegion(mD3D11Texture, 0, 0, 0, 0, *iter, 0, &box);
+  }
 
-    mD3D11SyncedTextures.clear();
-  }
+  mD3D11SyncedTextures.clear();
 }
 
 }
 }
--- a/gfx/layers/d3d11/TextureD3D11.h
+++ b/gfx/layers/d3d11/TextureD3D11.h
@@ -416,19 +416,23 @@ public:
   SyncObjectD3D11(SyncHandle aSyncHandle);
   virtual void FinalizeFrame();
 
   virtual SyncType GetSyncType() { return SyncType::D3D11; }
 
   void RegisterTexture(ID3D11Texture2D* aTexture);
 
 private:
+  bool Init();
+
+private:
+  SyncHandle mSyncHandle;
   RefPtr<ID3D11Texture2D> mD3D11Texture;
+  RefPtr<IDXGIKeyedMutex> mKeyedMutex;
   std::vector<ID3D11Texture2D*> mD3D11SyncedTextures;
-  SyncHandle mHandle;
 };
 
 inline uint32_t GetMaxTextureSizeForFeatureLevel(D3D_FEATURE_LEVEL aFeatureLevel)
 {
   int32_t maxTextureSize;
   switch (aFeatureLevel) {
   case D3D_FEATURE_LEVEL_11_1:
   case D3D_FEATURE_LEVEL_11_0:
--- a/gfx/layers/ipc/CompositorBridgeChild.cpp
+++ b/gfx/layers/ipc/CompositorBridgeChild.cpp
@@ -291,16 +291,34 @@ CompositorBridgeChild::Get()
 
 // static
 bool
 CompositorBridgeChild::ChildProcessHasCompositorBridge()
 {
   return sCompositorBridge != nullptr;
 }
 
+/* static */ bool
+CompositorBridgeChild::CompositorIsInGPUProcess()
+{
+  MOZ_ASSERT(NS_IsMainThread());
+
+  if (XRE_IsParentProcess()) {
+    return !!GPUProcessManager::Get()->GetGPUChild();
+  }
+
+  MOZ_ASSERT(XRE_IsContentProcess());
+  CompositorBridgeChild* bridge = CompositorBridgeChild::Get();
+  if (!bridge) {
+    return false;
+  }
+
+  return bridge->OtherPid() != dom::ContentChild::GetSingleton()->OtherPid();
+}
+
 PLayerTransactionChild*
 CompositorBridgeChild::AllocPLayerTransactionChild(const nsTArray<LayersBackend>& aBackendHints,
                                                    const uint64_t& aId,
                                                    TextureFactoryIdentifier*,
                                                    bool*)
 {
   LayerTransactionChild* c = new LayerTransactionChild(aId);
   c->AddIPDLReference();
--- a/gfx/layers/ipc/CompositorBridgeChild.h
+++ b/gfx/layers/ipc/CompositorBridgeChild.h
@@ -83,16 +83,20 @@ public:
     bool aUseAPZ,
     bool aUseExternalSurface,
     const gfx::IntSize& aSurfaceSize);
 
   static CompositorBridgeChild* Get();
 
   static bool ChildProcessHasCompositorBridge();
 
+  // Returns whether the compositor is in the GPU process (false if in the UI
+  // process). This may only be called on the main thread.
+  static bool CompositorIsInGPUProcess();
+
   void AddOverfillObserver(ClientLayerManager* aLayerManager);
 
   virtual mozilla::ipc::IPCResult
   RecvClearCachedResources(const uint64_t& id) override;
 
   virtual mozilla::ipc::IPCResult
   RecvDidComposite(const uint64_t& aId, const uint64_t& aTransactionId,
                    const TimeStamp& aCompositeStart,