Bug 944087. Fix main thread unlocking and tidy up. r=Bas

This commit is contained in:
Nicholas Cameron 2014-01-27 17:10:40 +13:00
parent 32ff80ba9d
commit 613fcb3cd7
5 changed files with 27 additions and 38 deletions

View File

@ -511,29 +511,29 @@ CompositorD3D9::EnsureSwapChain()
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;
}
@ -553,6 +553,7 @@ CompositorD3D9::Ready()
if (EnsureSwapChain()) {
// We don't need to call VerifyReadyForRendering because that is
// called by mSwapChain->PrepareForRendering() via EnsureSwapChain().
CheckResetCount();
return true;
}
@ -560,7 +561,7 @@ CompositorD3D9::Ready()
}
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();

View File

@ -672,11 +672,11 @@ DeviceManagerD3D9::SetShaderMode(ShaderMode aMode, Layer* aMask, bool aIs2D)
void
DeviceManagerD3D9::DestroyDevice()
{
++mDeviceResetCount;
mDeviceWasRemoved = true;
if (!IsD3D9Ex()) {
ReleaseTextureResources();
}
LayerManagerD3D9::OnDeviceManagerDestroy(this);
gfxWindowsPlatform::GetPlatform()->OnDeviceManagerDestroy(this);
}
@ -695,7 +695,6 @@ DeviceManagerD3D9::VerifyReadyForRendering()
if (FAILED(hr)) {
DestroyDevice();
++mDeviceResetCount;
return DeviceMustRecreate;
}
}
@ -724,6 +723,11 @@ DeviceManagerD3D9::VerifyReadyForRendering()
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
@ -733,9 +737,6 @@ DeviceManagerD3D9::VerifyReadyForRendering()
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
@ -743,18 +744,19 @@ DeviceManagerD3D9::VerifyReadyForRendering()
* 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;
}

View File

@ -34,12 +34,14 @@ const int CBvLayerQuad = 10;
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, the user should forget the current device manager
// and create a new one.
DeviceMustRecreate,
DeviceRetry
};

View File

@ -22,8 +22,6 @@
namespace mozilla {
namespace layers {
DeviceManagerD3D9 *LayerManagerD3D9::mDefaultDeviceManager = nullptr;
LayerManagerD3D9::LayerManagerD3D9(nsIWidget *aWidget)
: mWidget(aWidget)
, mDeviceResetCount(0)
@ -57,15 +55,9 @@ LayerManagerD3D9::Initialize(bool force)
}
}
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->
@ -233,10 +225,10 @@ LayerManagerD3D9::ReportFailure(const nsACString &aMsg, HRESULT aCode)
void
LayerManagerD3D9::Render()
{
DeviceManagerState state = mSwapChain->PrepareForRendering();
if (state != DeviceOK) {
if (mSwapChain->PrepareForRendering() != DeviceOK) {
return;
}
deviceManager()->SetupRenderState();
SetupPipeline();

View File

@ -124,11 +124,6 @@ public:
*/
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);
@ -137,9 +132,6 @@ public:
void SetCompositingDisabled(bool aCompositingDisabled) { mCompositingDisabled = aCompositingDisabled; }
private:
/* Default device manager instance */
static DeviceManagerD3D9 *mDefaultDeviceManager;
/* Device manager instance for this layer manager */
nsRefPtr<DeviceManagerD3D9> mDeviceManager;