Bug 1291163 - Make sure TextureHosts are read-unlock'ed if Compositor::EndFrame is not called. r=sotaro, a=ritu
authorNicolas Silva <nsilva@mozilla.com>
Tue, 09 Aug 2016 18:19:01 +0200
changeset 347709 0ed2f1ac56179d718bf9802dff06779d2687e3ef
parent 347708 6a401c72cdd376945ed93b525665bad830a85880
child 347710 ccba4736e261379bccb00e4310907cca142cdae7
push id6389
push userraliiev@mozilla.com
push dateMon, 19 Sep 2016 13:38:22 +0000
treeherdermozilla-beta@01d67bfe6c81 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssotaro, ritu
bugs1291163
milestone50.0a2
Bug 1291163 - Make sure TextureHosts are read-unlock'ed if Compositor::EndFrame is not called. r=sotaro, a=ritu
gfx/layers/PersistentBufferProvider.cpp
gfx/layers/d3d11/CompositorD3D11.cpp
--- a/gfx/layers/PersistentBufferProvider.cpp
+++ b/gfx/layers/PersistentBufferProvider.cpp
@@ -189,16 +189,25 @@ PersistentBufferProviderShared::BorrowDr
     }
   }
 
   if (!tex) {
     // We have to allocate a new texture.
     if (mTextures.length() >= 4) {
       // We should never need to buffer that many textures, something's wrong.
       MOZ_ASSERT(false);
+      // In theory we throttle the main thread when the compositor can't keep up,
+      // so we shoud never get in a situation where we sent 4 textures to the
+      // compositor and the latter as not released any of them.
+      // This seems to happen, however, in some edge cases such as just after a
+      // device reset (cf. Bug 1291163).
+      // It would be pretty bad to keep piling textures up at this point so we
+      // call NotifyInactive to remove some of our textures.
+      NotifyInactive();
+      // Give up now. The caller can fall-back to a non-shared buffer provider.
       return nullptr;
     }
 
     RefPtr<TextureClient> newTexture = TextureClient::CreateForDrawing(
       mFwd, mFormat, mSize,
       BackendSelector::Canvas,
       TextureFlags::DEFAULT,
       TextureAllocationFlags::ALLOC_DEFAULT
--- a/gfx/layers/d3d11/CompositorD3D11.cpp
+++ b/gfx/layers/d3d11/CompositorD3D11.cpp
@@ -1143,25 +1143,29 @@ CompositorD3D11::BeginFrame(const nsIntR
                             IntRect* aClipRectOut,
                             IntRect* aRenderBoundsOut)
 {
   // Don't composite if we are minimised. Other than for the sake of efficency,
   // this is important because resizing our buffers when mimised will fail and
   // cause a crash when we're restored.
   NS_ASSERTION(mHwnd, "Couldn't find an HWND when initialising?");
   if (::IsIconic(mHwnd) || mDevice->GetDeviceRemovedReason() != S_OK) {
+    // We are not going to render, and not going to call EndFrame so we have to
+    // read-unlock our textures to prevent them from accumulating.
+    ReadUnlockTextures();
     *aRenderBoundsOut = IntRect();
     return;
   }
 
   LayoutDeviceIntSize oldSize = mSize;
 
   // Failed to create a render target or the view.
   if (!UpdateRenderTarget() || !mDefaultRT || !mDefaultRT->mRTView ||
       mSize.width <= 0 || mSize.height <= 0) {
+    ReadUnlockTextures();
     *aRenderBoundsOut = IntRect();
     return;
   }
 
   IntRect intRect = IntRect(IntPoint(0, 0), mSize.ToUnknownSize());
   // Sometimes the invalid region is larger than we want to draw.
   nsIntRegion invalidRegionSafe;