Bug 1291163 - Make sure TextureHosts are read-unlock'ed if Compositor::EndFrame is not called. r=sotaro
authorNicolas Silva <nsilva@mozilla.com>
Tue, 09 Aug 2016 18:19:01 +0200
changeset 350122 9beaa75894056714aefe9737fbafc19afa3e8df7
parent 350121 65be64c62ed11d8e7c4a57ca30ad5859b7a70dd9
child 350123 578ebd592745ff2b7647b205576f20b5b36f3327
push id6570
push userraliiev@mozilla.com
push dateMon, 14 Nov 2016 12:26:13 +0000
treeherdermozilla-beta@f455459b2ae5 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssotaro
bugs1291163
milestone51.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1291163 - Make sure TextureHosts are read-unlock'ed if Compositor::EndFrame is not called. r=sotaro
gfx/layers/PersistentBufferProvider.cpp
gfx/layers/d3d11/CompositorD3D11.cpp
--- a/gfx/layers/PersistentBufferProvider.cpp
+++ b/gfx/layers/PersistentBufferProvider.cpp
@@ -267,16 +267,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;