Bug 944087 - Fix main thread unlocking and tidy up. r=Bas, a=lsblakk
authorNicholas Cameron <ncameron@mozilla.com>
Mon, 27 Jan 2014 17:10:40 +1300
changeset 176166 14d893faf45b523638b426f9bae76e4d16931a14
parent 176165 12c9107dd05095bc32469f846452241a43654b67
child 176167 f2569a4bbaf0843b2cc8cd4b1daa31d9efb10127
push id445
push userffxbld
push dateMon, 10 Mar 2014 22:05:19 +0000
treeherdermozilla-release@dc38b741b04e [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersBas, lsblakk
bugs944087
milestone28.0a2
Bug 944087 - Fix main thread unlocking and tidy up. r=Bas, a=lsblakk
gfx/layers/d3d9/CompositorD3D9.cpp
gfx/layers/d3d9/DeviceManagerD3D9.cpp
gfx/layers/d3d9/DeviceManagerD3D9.h
gfx/layers/d3d9/LayerManagerD3D9.cpp
gfx/layers/d3d9/LayerManagerD3D9.h
--- a/gfx/layers/d3d9/CompositorD3D9.cpp
+++ b/gfx/layers/d3d9/CompositorD3D9.cpp
@@ -479,39 +479,39 @@ CompositorD3D9::SetMask(const EffectChai
 bool
 CompositorD3D9::EnsureSwapChain()
 {
   MOZ_ASSERT(mDeviceManager, "Don't call EnsureSwapChain without a device manager");
 
   if (!mSwapChain) {
     mSwapChain = mDeviceManager->
       CreateSwapChain((HWND)mWidget->GetNativeData(NS_NATIVE_WINDOW));
+    // We could not create a swap chain, return false
     if (!mSwapChain) {
+      // Check the state of the device too
       DeviceManagerState state = mDeviceManager->VerifyReadyForRendering();
       if (state == DeviceMustRecreate) {
         mDeviceManager = nullptr;
-        mParent->SendInvalidateAll();
-      } else if (state == DeviceRetry) {
-        mParent->SendInvalidateAll();
       }
+      mParent->SendInvalidateAll();
       return false;
     }
   }
 
+  // We have a swap chain, lets initialise it
   DeviceManagerState state = mSwapChain->PrepareForRendering();
   if (state == DeviceOK) {
     return true;
   }
+  // Swap chain could not be initialised, handle the failure
   if (state == DeviceMustRecreate) {
     mDeviceManager = nullptr;
     mSwapChain = nullptr;
-    mParent->SendInvalidateAll();
-  } else if (state == DeviceRetry) {
-    mParent->SendInvalidateAll();
   }
+  mParent->SendInvalidateAll();
   return false;
 }
 
 void
 CompositorD3D9::CheckResetCount()
 {
   if (mDeviceResetCount != mDeviceManager->GetDeviceResetCount()) {
     mParent->SendInvalidateAll();
@@ -521,24 +521,25 @@ CompositorD3D9::CheckResetCount()
 
 bool
 CompositorD3D9::Ready()
 {
   if (mDeviceManager) {
     if (EnsureSwapChain()) {
       // We don't need to call VerifyReadyForRendering because that is
       // called by mSwapChain->PrepareForRendering() via EnsureSwapChain().
+
       CheckResetCount();
       return true;
     }
     return false;
   }
 
   NS_ASSERTION(!mCurrentRT && !mDefaultRT,
-                "Shouldn't have any render targets around, they must be released before our device");
+               "Shouldn't have any render targets around, they must be released before our device");
   mSwapChain = nullptr;
 
   mDeviceManager = gfxWindowsPlatform::GetPlatform()->GetD3D9DeviceManager();
   if (!mDeviceManager) {
     mParent->SendInvalidateAll();
     return false;
   }
   if (EnsureSwapChain()) {
--- a/gfx/layers/d3d9/DeviceManagerD3D9.cpp
+++ b/gfx/layers/d3d9/DeviceManagerD3D9.cpp
@@ -664,21 +664,21 @@ DeviceManagerD3D9::SetShaderMode(ShaderM
       SetShaderMode(aMode, MaskNone);
     }
   }
 }
 
 void
 DeviceManagerD3D9::DestroyDevice()
 {
+  ++mDeviceResetCount;
   mDeviceWasRemoved = true;
   if (!IsD3D9Ex()) {
     ReleaseTextureResources();
   }
-  LayerManagerD3D9::OnDeviceManagerDestroy(this);
   gfxWindowsPlatform::GetPlatform()->OnDeviceManagerDestroy(this);
 }
 
 DeviceManagerState
 DeviceManagerD3D9::VerifyReadyForRendering()
 {
   if (mDeviceWasRemoved) {
     return DeviceMustRecreate;
@@ -687,17 +687,16 @@ DeviceManagerD3D9::VerifyReadyForRenderi
   HRESULT hr = mDevice->TestCooperativeLevel();
 
   if (SUCCEEDED(hr)) {
     if (IsD3D9Ex()) {
       hr = mDeviceEx->CheckDeviceState(mFocusWnd);
 
       if (FAILED(hr)) {
         DestroyDevice();
-        ++mDeviceResetCount;
         return DeviceMustRecreate;
       }
     }
     return DeviceOK;
   }
 
   // We need to release all texture resources and swap chains before resetting.
   for (unsigned int i = 0; i < mLayersWithResources.Length(); i++) {
@@ -716,47 +715,50 @@ DeviceManagerD3D9::VerifyReadyForRenderi
   pp.BackBufferWidth = 1;
   pp.BackBufferHeight = 1;
   pp.BackBufferFormat = D3DFMT_A8R8G8B8;
   pp.SwapEffect = D3DSWAPEFFECT_DISCARD;
   pp.Windowed = TRUE;
   pp.PresentationInterval = D3DPRESENT_INTERVAL_DEFAULT;
   pp.hDeviceWindow = mFocusWnd;
 
+  // Whatever happens from now on, either we reset the device, or we should
+  // pretend we reset the device so that the layer manager or compositor
+  // doesn't ignore it.
+  ++mDeviceResetCount;
+
   // if we got this far, we know !SUCCEEDEED(hr), that means hr is one of
   // D3DERR_DEVICELOST, D3DERR_DEVICENOTRESET, D3DERR_DRIVERINTERNALERROR.
   // It is only worth resetting if we get D3DERR_DEVICENOTRESET. If we get
   // D3DERR_DEVICELOST we can wait and see if we get D3DERR_DEVICENOTRESET
   // later, then reset.
   if (hr == D3DERR_DEVICELOST) {
     HMONITOR hMonitorWindow;
     hMonitorWindow = MonitorFromWindow(mFocusWnd, MONITOR_DEFAULTTOPRIMARY);
     if (hMonitorWindow != mDeviceMonitor) {
-      /* The monitor has changed. We have to assume that the
-       * DEVICENOTRESET will not be comming. */
-
       /* jrmuizel: I'm not sure how to trigger this case. Usually, we get
        * DEVICENOTRESET right away and Reset() succeeds without going through a
        * set of DEVICELOSTs. This is presumeably because we don't call
        * VerifyReadyForRendering when we don't have any reason to paint.
        * Hopefully comparing HMONITORs is not overly aggressive.
        * See bug 626678.
        */
+      /* The monitor has changed. We have to assume that the
+       * DEVICENOTRESET will not be coming. */
+      DestroyDevice();
       return DeviceMustRecreate;
     }
-    return DeviceRetry;
+    return DeviceFail;
   }
   if (hr == D3DERR_DEVICENOTRESET) {
     hr = mDevice->Reset(&pp);
-    ++mDeviceResetCount;
   }
 
   if (FAILED(hr) || !CreateVertexBuffer()) {
     DestroyDevice();
-    ++mDeviceResetCount;
     return DeviceMustRecreate;
   }
 
   return DeviceOK;
 }
 
 bool
 DeviceManagerD3D9::VerifyCaps()
--- a/gfx/layers/d3d9/DeviceManagerD3D9.h
+++ b/gfx/layers/d3d9/DeviceManagerD3D9.h
@@ -29,22 +29,24 @@ const int CBmLayerTransform = 0;
 const int CBmProjection = 4;
 const int CBvRenderTargetOffset = 8;
 const int CBvTextureCoords = 9;
 const int CBvLayerQuad = 10;
 // we don't use opacity with solid color shaders
 const int CBfLayerOpacity = 0;
 const int CBvColor = 0;
 
-// TODO lower case this
 enum DeviceManagerState {
+  // The device and swap chain are OK.
   DeviceOK,
+  // The device or swap chain are in a bad state, and we should not render.
   DeviceFail,
+  // The device is lost and cannot be reset, the user should forget the
+  // current device manager and create a new one.
   DeviceMustRecreate,
-  DeviceRetry
 };
 
 
 /**
  * This structure is used to pass rectangles to our shader constant. We can use
  * this for passing rectangular areas to SetVertexShaderConstant. In the format
  * of a 4 component float(x,y,width,height). Our vertex shader can then use
  * this to construct rectangular positions from the 0,0-1,1 quad that we source
--- a/gfx/layers/d3d9/LayerManagerD3D9.cpp
+++ b/gfx/layers/d3d9/LayerManagerD3D9.cpp
@@ -17,18 +17,16 @@
 #include "gfxFailure.h"
 #include "mozilla/Preferences.h"
 
 #include "gfxCrashReporterUtils.h"
 
 namespace mozilla {
 namespace layers {
 
-DeviceManagerD3D9 *LayerManagerD3D9::mDefaultDeviceManager = nullptr;
-
 LayerManagerD3D9::LayerManagerD3D9(nsIWidget *aWidget)
   : mWidget(aWidget)
   , mDeviceResetCount(0)
 {
   mCurrentCallbackInfo.Callback = nullptr;
   mCurrentCallbackInfo.CallbackData = nullptr;
 }
 
@@ -52,25 +50,19 @@ LayerManagerD3D9::Initialize(bool force)
       if (status != nsIGfxInfo::FEATURE_NO_INFO && !forceAccelerate)
       {
         NS_WARNING("Direct3D 9-accelerated layers are not supported on this system.");
         return false;
       }
     }
   }
 
-  if (!mDefaultDeviceManager) {
-    mDeviceManager = gfxWindowsPlatform::GetPlatform()->GetD3D9DeviceManager();
-    if (!mDeviceManager) {
-      return false;
-    }
-
-    mDefaultDeviceManager = mDeviceManager;
-  } else {
-    mDeviceManager = mDefaultDeviceManager;
+  mDeviceManager = gfxWindowsPlatform::GetPlatform()->GetD3D9DeviceManager();
+  if (!mDeviceManager) {
+    return false;
   }
 
   mSwapChain = mDeviceManager->
     CreateSwapChain((HWND)mWidget->GetNativeData(NS_NATIVE_WINDOW));
 
   if (!mSwapChain) {
     return false;
   }
@@ -228,20 +220,20 @@ LayerManagerD3D9::ReportFailure(const ns
   NS_WARNING(msg.BeginReading());
 
   gfx::LogFailure(msg);
 }
 
 void
 LayerManagerD3D9::Render()
 {
-  DeviceManagerState state = mSwapChain->PrepareForRendering();
-  if (state != DeviceOK) {
+  if (mSwapChain->PrepareForRendering() != DeviceOK) {
     return;
   }
+
   deviceManager()->SetupRenderState();
 
   SetupPipeline();
 
   if (CompositingDisabled()) {
     static_cast<LayerD3D9*>(mRoot->ImplData())->RenderLayer();
     return;
   }
--- a/gfx/layers/d3d9/LayerManagerD3D9.h
+++ b/gfx/layers/d3d9/LayerManagerD3D9.h
@@ -119,32 +119,24 @@ public:
   IDirect3DDevice9 *device() const { return mDeviceManager->device(); }
   DeviceManagerD3D9 *deviceManager() const { return mDeviceManager; }
 
   /** 
    * Return pointer to the Nv3DVUtils instance. Re-direct to mDeviceManager.
    */ 
   Nv3DVUtils *GetNv3DVUtils() { return mDeviceManager ? mDeviceManager->GetNv3DVUtils() : nullptr; } 
 
-  static void OnDeviceManagerDestroy(DeviceManagerD3D9 *aDeviceManager) {
-    if(aDeviceManager == mDefaultDeviceManager)
-      mDefaultDeviceManager = nullptr;
-  }
-
   virtual const char* Name() const { return "D3D9"; }
 
   void ReportFailure(const nsACString &aMsg, HRESULT aCode);
 
   bool CompositingDisabled() { return mCompositingDisabled; }
   void SetCompositingDisabled(bool aCompositingDisabled) { mCompositingDisabled = aCompositingDisabled; }
 
 private:
-  /* Default device manager instance */
-  static DeviceManagerD3D9 *mDefaultDeviceManager;
-
   /* Device manager instance for this layer manager */
   nsRefPtr<DeviceManagerD3D9> mDeviceManager;
 
   /* Swap chain associated with this layer manager */
   nsRefPtr<SwapChainD3D9> mSwapChain;
 
   /* Widget associated with this layer manager */
   nsIWidget *mWidget;