Bug 1143653 - Crash in CompositorD3D9 rather than TextureD3D9 if device reset fails, after a few attemps. r=jrmuizel

This commit is contained in:
Nicolas Silva 2015-03-17 15:05:41 +01:00
parent bbc180d767
commit 0357c19122
5 changed files with 30 additions and 5 deletions

View File

@ -27,6 +27,7 @@ CompositorD3D9::CompositorD3D9(PCompositorParent* aParent, nsIWidget *aWidget)
: Compositor(aParent) : Compositor(aParent)
, mWidget(aWidget) , mWidget(aWidget)
, mDeviceResetCount(0) , mDeviceResetCount(0)
, mFailedResetAttemps(0)
{ {
Compositor::SetBackend(LayersBackend::LAYERS_D3D9); Compositor::SetBackend(LayersBackend::LAYERS_D3D9);
} }
@ -558,6 +559,7 @@ CompositorD3D9::EnsureSwapChain()
// We have a swap chain, lets initialise it // We have a swap chain, lets initialise it
DeviceManagerState state = mSwapChain->PrepareForRendering(); DeviceManagerState state = mSwapChain->PrepareForRendering();
if (state == DeviceOK) { if (state == DeviceOK) {
mFailedResetAttemps = 0;
return true; return true;
} }
// Swap chain could not be initialised, handle the failure // Swap chain could not be initialised, handle the failure
@ -585,10 +587,10 @@ CompositorD3D9::Ready()
if (EnsureSwapChain()) { if (EnsureSwapChain()) {
// We don't need to call VerifyReadyForRendering because that is // We don't need to call VerifyReadyForRendering because that is
// called by mSwapChain->PrepareForRendering() via EnsureSwapChain(). // called by mSwapChain->PrepareForRendering() via EnsureSwapChain().
CheckResetCount(); CheckResetCount();
return true; return true;
} }
FailedToResetDevice();
return false; return false;
} }
@ -598,6 +600,7 @@ CompositorD3D9::Ready()
mDeviceManager = gfxWindowsPlatform::GetPlatform()->GetD3D9DeviceManager(); mDeviceManager = gfxWindowsPlatform::GetPlatform()->GetD3D9DeviceManager();
if (!mDeviceManager) { if (!mDeviceManager) {
FailedToResetDevice();
mParent->SendInvalidateAll(); mParent->SendInvalidateAll();
return false; return false;
} }
@ -608,6 +611,19 @@ CompositorD3D9::Ready()
return false; return false;
} }
void
CompositorD3D9::FailedToResetDevice() {
mFailedResetAttemps += 1;
auto withoutAssertion = CriticalLog::DefaultOptions(false);
gfxCriticalError(withoutAssertion) << "[D3D9] Failed to re-create a D3D9 device, attempt "
<< mFailedResetAttemps;
// 10 is a totally arbitrary number that we may want to increase or decrease
// depending on how things behave in the wild.
if (mFailedResetAttemps > 10) {
MOZ_CRASH("Unable to get a working D3D9 Compositor");
}
}
void void
CompositorD3D9::BeginFrame(const nsIntRegion& aInvalidRegion, CompositorD3D9::BeginFrame(const nsIntRegion& aInvalidRegion,
const Rect *aClipRectIn, const Rect *aClipRectIn,

View File

@ -146,6 +146,8 @@ private:
*/ */
void CheckResetCount(); void CheckResetCount();
void FailedToResetDevice();
void ReportFailure(const nsACString &aMsg, HRESULT aCode); void ReportFailure(const nsACString &aMsg, HRESULT aCode);
virtual gfx::IntSize GetWidgetSize() const MOZ_OVERRIDE virtual gfx::IntSize GetWidgetSize() const MOZ_OVERRIDE
@ -168,6 +170,7 @@ private:
nsIntSize mSize; nsIntSize mSize;
uint32_t mDeviceResetCount; uint32_t mDeviceResetCount;
uint32_t mFailedResetAttemps;
}; };
} }

View File

@ -301,8 +301,8 @@ DeviceManagerD3D9::Init()
&pp, &pp,
getter_AddRefs(mDevice)); getter_AddRefs(mDevice));
if (FAILED(hr)) { if (FAILED(hr) || !mDevice) {
gfxCriticalError() << "[D3D9] Failed to create the device"; gfxCriticalError() << "[D3D9] Failed to create the device, code: " << hexa(hr);
return false; return false;
} }
} }

View File

@ -825,6 +825,10 @@ DataTextureSourceD3D9::UpdateFromTexture(IDirect3DTexture9* aTexture,
} }
DeviceManagerD3D9* dm = gfxWindowsPlatform::GetPlatform()->GetD3D9DeviceManager(); DeviceManagerD3D9* dm = gfxWindowsPlatform::GetPlatform()->GetD3D9DeviceManager();
if (!dm || !dm->device()) {
return false;
}
if (!mTexture) { if (!mTexture) {
mTexture = dm->CreateTexture(mSize, SurfaceFormatToD3D9Format(mFormat), mTexture = dm->CreateTexture(mSize, SurfaceFormatToD3D9Format(mFormat),
D3DPOOL_DEFAULT, this); D3DPOOL_DEFAULT, this);
@ -889,7 +893,9 @@ TextureHostD3D9::Updated(const nsIntRegion* aRegion)
nullptr, mFlags); nullptr, mFlags);
} }
mTextureSource->UpdateFromTexture(mTexture, aRegion); if (!mTextureSource->UpdateFromTexture(mTexture, aRegion)) {
gfxCriticalError() << "[D3D9] DataTextureSourceD3D9::UpdateFromTexture failed";
}
} }
IDirect3DDevice9* IDirect3DDevice9*

View File

@ -1550,7 +1550,7 @@ gfxWindowsPlatform::GetD3D9DeviceManager()
CompositorParent::IsInCompositorThread())) { CompositorParent::IsInCompositorThread())) {
mDeviceManager = new DeviceManagerD3D9(); mDeviceManager = new DeviceManagerD3D9();
if (!mDeviceManager->Init()) { if (!mDeviceManager->Init()) {
NS_WARNING("Could not initialise device manager"); gfxCriticalError() << "[D3D9] Could not Initialize the DeviceManagerD3D9";
mDeviceManager = nullptr; mDeviceManager = nullptr;
} }
} }