Bug 1300121 - Flush the D3D11 immediate context if a composition is cancelled to avoid resources queing up in the driver. r=Bas
authorNicolas Silva <nsilva@mozilla.com>
Tue, 11 Oct 2016 14:10:22 +0200
changeset 324246 c10416d7247dc397630f15783789176e5affe959
parent 324245 40d30f945799a475a9e6134ba0d1dcc3ff534e35
child 324247 f96d497c78a7f3d73d8e5079e2fcb1eca80e574f
push id24
push usermaklebus@msu.edu
push dateTue, 20 Dec 2016 03:11:33 +0000
reviewersBas
bugs1300121
milestone53.0a1
Bug 1300121 - Flush the D3D11 immediate context if a composition is cancelled to avoid resources queing up in the driver. r=Bas
gfx/layers/Compositor.h
gfx/layers/composite/LayerManagerComposite.cpp
gfx/layers/d3d11/CompositorD3D11.cpp
gfx/layers/d3d11/CompositorD3D11.h
--- a/gfx/layers/Compositor.h
+++ b/gfx/layers/Compositor.h
@@ -422,16 +422,18 @@ public:
 
   /**
    * Flush the current frame to the screen and tidy up.
    *
    * Derived class overriding this should call Compositor::EndFrame.
    */
   virtual void EndFrame();
 
+  virtual void CancelFrame() { ReadUnlockTextures(); }
+
   virtual void SetDispAcquireFence(Layer* aLayer);
 
   /**
    * Whether textures created by this compositor can receive partial updates.
    */
   virtual bool SupportsPartialTextureUpdate() = 0;
 
   void SetDiagnosticTypes(DiagnosticTypes aDiagnostics)
--- a/gfx/layers/composite/LayerManagerComposite.cpp
+++ b/gfx/layers/composite/LayerManagerComposite.cpp
@@ -145,16 +145,17 @@ LayerManagerComposite::~LayerManagerComp
 void
 LayerManagerComposite::Destroy()
 {
   if (!mDestroyed) {
     mCompositor->GetWidget()->CleanupWindowEffects();
     if (mRoot) {
       RootLayer()->Destroy();
     }
+    mCompositor->CancelFrame();
     mRoot = nullptr;
     mClonedLayerTreeProperties = nullptr;
     mPaintCounter = nullptr;
     mDestroyed = true;
   }
 }
 
 void
@@ -1315,16 +1316,19 @@ LayerManagerComposite::AutoAddMaskEffect
   }
 
   mCompositable->RemoveMaskEffect();
 }
 
 void
 LayerManagerComposite::ChangeCompositor(Compositor* aNewCompositor)
 {
+  if (mCompositor) {
+    mCompositor->CancelFrame();
+  }
   mCompositor = aNewCompositor;
   mTextRenderer = new TextRenderer(aNewCompositor);
   mTwoPassTmpTarget = nullptr;
 }
 
 LayerComposite::LayerComposite(LayerManagerComposite *aManager)
   : HostLayer(aManager)
   , mCompositeManager(aManager)
--- a/gfx/layers/d3d11/CompositorD3D11.cpp
+++ b/gfx/layers/d3d11/CompositorD3D11.cpp
@@ -1026,16 +1026,17 @@ CompositorD3D11::BeginFrame(const nsIntR
   IntRect invalidRect = invalidRegionSafe.GetBounds();
 
   IntRect clipRect = invalidRect;
   if (aClipRectIn) {
     clipRect.IntersectRect(clipRect, IntRect(aClipRectIn->x, aClipRectIn->y, aClipRectIn->width, aClipRectIn->height));
   }
 
   if (clipRect.IsEmpty()) {
+    CancelFrame();
     *aRenderBoundsOut = IntRect();
     return;
   }
 
   mContext->IASetInputLayout(mAttachments->mInputLayout);
 
   ID3D11Buffer* buffer = mAttachments->mVertexBuffer;
   UINT size = sizeof(Vertex);
@@ -1180,16 +1181,25 @@ CompositorD3D11::EndFrame()
   mQuery = query;
 
   Compositor::EndFrame();
 
   mCurrentRT = nullptr;
 }
 
 void
+CompositorD3D11::CancelFrame()
+{
+  ReadUnlockTextures();
+  // Flush the context, otherwise the driver might hold some resources alive
+  // until the next flush or present.
+  mContext->Flush();
+}
+
+void
 CompositorD3D11::PrepareViewport(const gfx::IntSize& aSize)
 {
   // This view matrix translates coordinates from 0..width and 0..height to
   // -1..1 on the X axis, and -1..1 on the Y axis (flips the Y coordinate)
   Matrix viewMatrix = Matrix::Translation(-1.0, 1.0);
   viewMatrix.PreScale(2.0f / float(aSize.width), 2.0f / float(aSize.height));
   viewMatrix.PreScale(1.0f, -1.0f);
 
--- a/gfx/layers/d3d11/CompositorD3D11.h
+++ b/gfx/layers/d3d11/CompositorD3D11.h
@@ -110,16 +110,18 @@ public:
                           gfx::IntRect *aClipRectOut = nullptr,
                           gfx::IntRect *aRenderBoundsOut = nullptr) override;
 
   /**
    * Flush the current frame to the screen.
    */
   virtual void EndFrame() override;
 
+  virtual void CancelFrame() override;
+
   /**
    * Setup the viewport and projection matrix for rendering
    * to a window of the given dimensions.
    */
   virtual void PrepareViewport(const gfx::IntSize& aSize);
   virtual void PrepareViewport(const gfx::IntSize& aSize, const gfx::Matrix4x4& aProjection,
                                float aZNear, float aZFar);