Don't use nsIGfxInfo in CompositorD3D11. (bug 1294339, r=mattwoodrow)
authorDavid Anderson <danderson@mozilla.com>
Sat, 13 Aug 2016 12:12:51 -0700
changeset 309374 6e3fb17d70ad6b8b478f2be3c9a7268fc45b83be
parent 309373 b065da4afcf193e6d2ecd0897d9556a53258988a
child 309375 8d1cf3481e5fc417943e280a45537b054272e3f9
push id30561
push userkwierso@gmail.com
push dateMon, 15 Aug 2016 21:20:49 +0000
treeherdermozilla-central@91a319101587 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmattwoodrow
bugs1294339
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
Don't use nsIGfxInfo in CompositorD3D11. (bug 1294339, r=mattwoodrow)
gfx/layers/d3d11/CompositorD3D11.cpp
gfx/layers/d3d11/CompositorD3D11.h
gfx/thebes/moz.build
--- a/gfx/layers/d3d11/CompositorD3D11.cpp
+++ b/gfx/layers/d3d11/CompositorD3D11.cpp
@@ -5,17 +5,17 @@
 
 #include "CompositorD3D11.h"
 
 #include "TextureD3D11.h"
 #include "CompositorD3D11Shaders.h"
 
 #include "gfxWindowsPlatform.h"
 #include "nsIWidget.h"
-#include "nsIGfxInfo.h"
+#include "mozilla/gfx/D3D11Checks.h"
 #include "mozilla/gfx/DeviceManagerD3D11.h"
 #include "mozilla/layers/ImageHost.h"
 #include "mozilla/layers/ContentHost.h"
 #include "mozilla/layers/Effects.h"
 #include "nsWindowsHelpers.h"
 #include "gfxPrefs.h"
 #include "gfxConfig.h"
 #include "gfxCrashReporterUtils.h"
@@ -30,16 +30,18 @@
 #include <dxgi1_2.h>
 
 namespace mozilla {
 
 using namespace gfx;
 
 namespace layers {
 
+static bool CanUsePartialPresents(ID3D11Device* aDevice);
+
 struct Vertex
 {
     float position[2];
 };
 
 // {1E4D7BEB-D8EC-4A0B-BF0A-63E6DE129425}
 static const GUID sDeviceAttachmentsD3D11 =
 { 0x1e4d7beb, 0xd8ec, 0x4a0b, { 0xbf, 0xa, 0x63, 0xe6, 0xde, 0x12, 0x94, 0x25 } };
@@ -136,16 +138,17 @@ private:
   bool mInitOkay;
 };
 
 CompositorD3D11::CompositorD3D11(CompositorBridgeParent* aParent, widget::CompositorWidget* aWidget)
   : Compositor(aWidget, aParent)
   , mAttachments(nullptr)
   , mHwnd(nullptr)
   , mDisableSequenceForNextFrame(false)
+  , mAllowPartialPresents(false)
   , mVerifyBuffersFailed(false)
 {
 }
 
 CompositorD3D11::~CompositorD3D11()
 {
   if (mDevice) {
     int referenceCount = 0;
@@ -181,17 +184,16 @@ CompositorD3D11::Initialize(nsCString* c
 
   mDevice = DeviceManagerD3D11::Get()->GetCompositorDevice();
   if (!mDevice) {
     *out_failureReason = "FEATURE_FAILURE_D3D11_NO_DEVICE";
     return false;
   }
 
   mDevice->GetImmediateContext(getter_AddRefs(mContext));
-
   if (!mContext) {
     gfxCriticalNote << "[D3D11] failed to get immediate context";
     *out_failureReason = "FEATURE_FAILURE_D3D11_CONTEXT";
     return false;
   }
 
   mFeatureLevel = mDevice->GetFeatureLevel();
 
@@ -401,17 +403,44 @@ CompositorD3D11::Initialize(nsCString* c
                                        DXGI_MWA_NO_WINDOW_CHANGES);
   }
 
   if (!mWidget->InitCompositor(this)) {
     *out_failureReason = "FEATURE_FAILURE_D3D11_INIT_COMPOSITOR";
     return false;
   }
 
+  mAllowPartialPresents = CanUsePartialPresents(mDevice);
+
   reporter.SetSuccessful();
+  return true;
+}
+
+static bool
+CanUsePartialPresents(ID3D11Device* aDevice)
+{
+  if (gfxPrefs::PartialPresent() > 0) {
+    return true;
+  }
+  if (gfxPrefs::PartialPresent() < 0) {
+    return false;
+  }
+  if (DeviceManagerD3D11::Get()->IsWARP()) {
+    return true;
+  }
+
+  DXGI_ADAPTER_DESC desc;
+  if (!D3D11Checks::GetDxgiDesc(aDevice, &desc)) {
+    return false;
+  }
+
+  // We have to disable partial presents on NVIDIA (bug 1189940).
+  if (desc.VendorId == 0x10de) {
+    return false;
+  }
 
   return true;
 }
 
 already_AddRefed<DataTextureSource>
 CompositorD3D11::CreateDataTextureSource(TextureFlags aFlags)
 {
   RefPtr<DataTextureSource> result = new DataTextureSourceD3D11(gfx::SurfaceFormat::UNKNOWN,
@@ -1066,33 +1095,18 @@ CompositorD3D11::EndFrame()
     // to tear when rendering. When not using WARP it appears the DWM takes
     // care of tearing for us.
     presentInterval = 1;
   }
 
   if (oldSize == mSize) {
     RefPtr<IDXGISwapChain1> chain;
     HRESULT hr = mSwapChain->QueryInterface((IDXGISwapChain1**)getter_AddRefs(chain));
-    // We can force partial present or block partial present, based on the value of
-    // this preference; the default is to disable it on Nvidia (bug 1189940)
-    bool allowPartialPresent = false;
 
-    int32_t partialPresentPref = gfxPrefs::PartialPresent();
-    if (partialPresentPref > 0) {
-      allowPartialPresent = true;
-    } else if (partialPresentPref < 0) {
-      allowPartialPresent = false;
-    } else if (partialPresentPref == 0) {
-      nsString vendorID;
-      nsCOMPtr<nsIGfxInfo> gfxInfo = services::GetGfxInfo();
-      gfxInfo->GetAdapterVendorID(vendorID);
-      allowPartialPresent = !vendorID.EqualsLiteral("0x10de") || isWARP;
-    }
-
-    if (SUCCEEDED(hr) && chain && allowPartialPresent) {
+    if (SUCCEEDED(hr) && chain && mAllowPartialPresents) {
       DXGI_PRESENT_PARAMETERS params;
       PodZero(&params);
       params.DirtyRectsCount = mInvalidRegion.GetNumRects();
       StackArray<RECT, 4> rects(params.DirtyRectsCount);
 
       uint32_t i = 0;
       for (auto iter = mInvalidRegion.RectIter(); !iter.Done(); iter.Next()) {
         const IntRect& r = iter.Get();
--- a/gfx/layers/d3d11/CompositorD3D11.h
+++ b/gfx/layers/d3d11/CompositorD3D11.h
@@ -186,16 +186,17 @@ private:
 
   HWND mHwnd;
 
   D3D_FEATURE_LEVEL mFeatureLevel;
 
   VertexShaderConstants mVSConstants;
   PixelShaderConstants mPSConstants;
   bool mDisableSequenceForNextFrame;
+  bool mAllowPartialPresents;
 
   gfx::IntRect mInvalidRect;
   // This is the clip rect applied to the default DrawTarget (i.e. the window)
   gfx::IntRect mCurrentClip;
   nsIntRegion mInvalidRegion;
 
   bool mVerifyBuffersFailed;
 };
--- a/gfx/thebes/moz.build
+++ b/gfx/thebes/moz.build
@@ -46,16 +46,17 @@ EXPORTS += [
     'gfxUserFontSet.h',
     'gfxUtils.h',
     'RoundedRect.h',
     'SoftwareVsyncSource.h',
     'VsyncSource.h',
 ]
 
 EXPORTS.mozilla.gfx += [
+    'D3D11Checks.h',
     'DeviceManagerD3D11.h',
     'PrintTarget.h',
     'PrintTargetThebes.h',
 ]
 
 if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'android':
     EXPORTS += [
         'gfxAndroidPlatform.h',