Bug 1260611 - Part 2: Block CompositorD3D11 after presenting until the previous frame is complete. r=Bas a=ritu
authorMatt Woodrow <mwoodrow@mozilla.com>
Wed, 11 May 2016 10:53:46 +1200
changeset 378924 fa709c256861d88fa9d2bd7d2e0ad4a4f30c58ee
parent 378923 f9dd2fb1b99188f72b429a9e126e90a6ab50d0d1
child 378925 7c3ef5d06736bc63d138975a7194050569c62636
push id21011
push usermak77@bonardo.net
push dateThu, 16 Jun 2016 13:40:45 +0000
reviewersBas, ritu
bugs1260611
milestone47.0
Bug 1260611 - Part 2: Block CompositorD3D11 after presenting until the previous frame is complete. r=Bas a=ritu
gfx/layers/d3d11/CompositorD3D11.cpp
gfx/layers/d3d11/CompositorD3D11.h
--- a/gfx/layers/d3d11/CompositorD3D11.cpp
+++ b/gfx/layers/d3d11/CompositorD3D11.cpp
@@ -1223,16 +1223,23 @@ CompositorD3D11::EndFrame()
   }
 
   LayoutDeviceIntSize oldSize = mSize;
   EnsureSize();
   if (mSize.width <= 0 || mSize.height <= 0) {
     return;
   }
 
+  RefPtr<ID3D11Query> query;
+  CD3D11_QUERY_DESC  desc(D3D11_QUERY_EVENT);
+  mDevice->CreateQuery(&desc, getter_AddRefs(query));
+  if (query) {
+    mContext->End(query);
+  }
+
   UINT presentInterval = 0;
 
   if (gfxWindowsPlatform::GetPlatform()->IsWARP()) {
     // When we're using WARP we cannot present immediately as it causes us
     // to tear when rendering. When not using WARP it appears the DWM takes
     // care of tearing for us.
     presentInterval = 1;
   }
@@ -1283,16 +1290,33 @@ CompositorD3D11::EndFrame()
       }
     }
     mDisableSequenceForNextFrame = false;
     if (mTarget) {
       PaintToTarget();
     }
   }
 
+  // Block until the previous frame's work has been completed.
+  if (mQuery) {
+    TimeStamp start = TimeStamp::Now();
+    BOOL result;
+    while (mContext->GetData(mQuery, &result, sizeof(BOOL), 0) != S_OK) {
+      if (mDevice->GetDeviceRemovedReason() != S_OK) {
+        break;
+      }
+      if ((TimeStamp::Now() - start) > TimeDuration::FromSeconds(2)) {
+        break;
+      }
+      Sleep(0);
+    }
+  }
+  // Store the query for this frame so we can flush it next time.
+  mQuery = query;
+
   mCurrentRT = nullptr;
 }
 
 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)
--- a/gfx/layers/d3d11/CompositorD3D11.h
+++ b/gfx/layers/d3d11/CompositorD3D11.h
@@ -183,16 +183,18 @@ private:
                     RefPtr<ID3D11ShaderResourceView>* aOutView);
 
   RefPtr<ID3D11DeviceContext> mContext;
   RefPtr<ID3D11Device> mDevice;
   RefPtr<IDXGISwapChain> mSwapChain;
   RefPtr<CompositingRenderTargetD3D11> mDefaultRT;
   RefPtr<CompositingRenderTargetD3D11> mCurrentRT;
 
+  RefPtr<ID3D11Query> mQuery;
+
   DeviceAttachmentsD3D11* mAttachments;
 
   nsIWidget* mWidget;
 
   LayoutDeviceIntSize mSize;
 
   HWND mHwnd;