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)
, mWidget(aWidget)
, mDeviceResetCount(0)
, mFailedResetAttemps(0)
{
Compositor::SetBackend(LayersBackend::LAYERS_D3D9);
}
@ -558,6 +559,7 @@ CompositorD3D9::EnsureSwapChain()
// We have a swap chain, lets initialise it
DeviceManagerState state = mSwapChain->PrepareForRendering();
if (state == DeviceOK) {
mFailedResetAttemps = 0;
return true;
}
// Swap chain could not be initialised, handle the failure
@ -585,10 +587,10 @@ CompositorD3D9::Ready()
if (EnsureSwapChain()) {
// We don't need to call VerifyReadyForRendering because that is
// called by mSwapChain->PrepareForRendering() via EnsureSwapChain().
CheckResetCount();
return true;
}
FailedToResetDevice();
return false;
}
@ -598,6 +600,7 @@ CompositorD3D9::Ready()
mDeviceManager = gfxWindowsPlatform::GetPlatform()->GetD3D9DeviceManager();
if (!mDeviceManager) {
FailedToResetDevice();
mParent->SendInvalidateAll();
return false;
}
@ -608,6 +611,19 @@ CompositorD3D9::Ready()
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
CompositorD3D9::BeginFrame(const nsIntRegion& aInvalidRegion,
const Rect *aClipRectIn,

View File

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

View File

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

View File

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

View File

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