Bug 1260611 - Part 2: Block CompositorD3D11 after presenting until the previous frame is complete. r=Bas a=ritu
☠☠ backed out by 4f7c3a2567f8 ☠ ☠
authorMatt Woodrow <mwoodrow@mozilla.com>
Wed, 11 May 2016 10:53:46 +1200
changeset 333021 e5dc1c7fcb08356caa6f5dd7568e52463f1f0459
parent 333020 4a4cf532f07c9ae9c880f8c1920ef9211d48922a
child 333022 b91fad4c1ea76eeaeb54898761314fc079fa073d
push id6048
push userkmoir@mozilla.com
push dateMon, 06 Jun 2016 19:02:08 +0000
treeherdermozilla-beta@46d72a56c57d [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersBas, ritu
bugs1260611
milestone48.0a2
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
@@ -1204,16 +1204,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;
   }
@@ -1264,16 +1271,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
@@ -184,16 +184,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;