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 324739 28e269b5ab120e15b7cf22f082befb1ed00cd5d5
parent 324736 a544ec8cb49864b7c8ff2921e47c9b64160ac1e7
child 324740 e10cae7946b2581b3737771d456f4474734c63f7
push id24
push usermaklebus@msu.edu
push dateTue, 20 Dec 2016 03:11:33 +0000
reviewersmattwoodrow
bugs1319557
milestone53.0a1
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,