Bug 623807: Do not use the GDI compatibility flag for the swap chain on optimus devices. r=jrmuizel a=blocking-beta9
authorBas Schouten <bschouten@mozilla.com>
Sat, 08 Jan 2011 06:39:15 +0100
changeset 60236 2aa85f69c1a4c6216cd2f663916146cfd5cb33c8
parent 60235 aacbdfc1029e8197832100685b0a5f9e2f95b754
child 60237 8f1c39add00f29c2e9d4ce65b015cea4d3c28ffd
push id17894
push userbschouten@mozilla.com
push dateSat, 08 Jan 2011 05:40:26 +0000
treeherdermozilla-central@2aa85f69c1a4 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjrmuizel, blocking-beta9
bugs623807
milestone2.0b9pre
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 623807: Do not use the GDI compatibility flag for the swap chain on optimus devices. r=jrmuizel a=blocking-beta9
gfx/layers/d3d10/LayerManagerD3D10.cpp
--- a/gfx/layers/d3d10/LayerManagerD3D10.cpp
+++ b/gfx/layers/d3d10/LayerManagerD3D10.cpp
@@ -82,16 +82,22 @@ LayerManagerD3D10::LayerManagerD3D10(nsI
 {
 }
 
 LayerManagerD3D10::~LayerManagerD3D10()
 {
   Destroy();
 }
 
+static bool
+IsOptimus()
+{
+  return GetModuleHandleA("nvumdshim.dll");
+}
+
 bool
 LayerManagerD3D10::Initialize()
 {
   HRESULT hr;
 
   mDevice = gfxWindowsPlatform::GetPlatform()->GetD3D10Device();
   if (!mDevice) {
       return false;
@@ -177,18 +183,25 @@ LayerManagerD3D10::Initialize()
   swapDesc.BufferDesc.RefreshRate.Numerator = 60;
   swapDesc.BufferDesc.RefreshRate.Denominator = 1;
   swapDesc.SampleDesc.Count = 1;
   swapDesc.SampleDesc.Quality = 0;
   swapDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
   swapDesc.BufferCount = 1;
   // We don't really need this flag, however it seems on some NVidia hardware
   // smaller area windows do not present properly without this flag. This flag
-  // should have no negative consequences by itself. See bug 613790.
-  swapDesc.Flags = DXGI_SWAP_CHAIN_FLAG_GDI_COMPATIBLE;
+  // should have no negative consequences by itself. See bug 613790. This flag
+  // is broken on optimus devices. As a temporary solution we don't set it
+  // there, the only way of reliably detecting we're on optimus is looking for
+  // the DLL. See Bug 623807.
+  if (IsOptimus()) {
+    swapDesc.Flags = 0;
+  } else {
+    swapDesc.Flags = DXGI_SWAP_CHAIN_FLAG_GDI_COMPATIBLE;
+  }
   swapDesc.OutputWindow = (HWND)mWidget->GetNativeData(NS_NATIVE_WINDOW);
   swapDesc.Windowed = TRUE;
 
   /**
    * Create a swap chain, this swap chain will contain the backbuffer for
    * the window we draw to. The front buffer is the full screen front
    * buffer.
    */
@@ -429,19 +442,25 @@ LayerManagerD3D10::VerifyBufferSize()
   mWidget->GetClientBounds(rect);
 
   if (swapDesc.BufferDesc.Width == rect.width &&
       swapDesc.BufferDesc.Height == rect.height) {
     return;
   }
 
   mRTView = nsnull;
-  mSwapChain->ResizeBuffers(1, rect.width, rect.height,
-                            DXGI_FORMAT_B8G8R8A8_UNORM,
-                            DXGI_SWAP_CHAIN_FLAG_GDI_COMPATIBLE);
+  if (IsOptimus()) {
+    mSwapChain->ResizeBuffers(1, rect.width, rect.height,
+                              DXGI_FORMAT_B8G8R8A8_UNORM,
+                              0);
+  } else {
+    mSwapChain->ResizeBuffers(1, rect.width, rect.height,
+                              DXGI_FORMAT_B8G8R8A8_UNORM,
+                              DXGI_SWAP_CHAIN_FLAG_GDI_COMPATIBLE);
+  }
 
 }
 
 void
 LayerManagerD3D10::Render()
 {
   if (mRoot) {
     static_cast<LayerD3D10*>(mRoot->ImplData())->Validate();