Bug 1257375: If the first adapter found is 0/0, look for a valid device using the alternative approach (already used for the second GPU detection.) r?kats draft
authorMilan Sreckovic <milan@mozilla.com>
Tue, 11 Apr 2017 21:39:20 -0400
changeset 560870 21205f3953723f5143a6554c9596b28b4484ddf7
parent 560546 abf145ebd05fe105efbc78b761858c34f7690154
child 623825 afb7d273ff6538b973454a7c3dc4519328afe657
push id53567
push userbmo:milan@mozilla.com
push dateWed, 12 Apr 2017 01:41:46 +0000
reviewerskats
bugs1257375
milestone55.0a1
Bug 1257375: If the first adapter found is 0/0, look for a valid device using the alternative approach (already used for the second GPU detection.) r?kats MozReview-Commit-ID: FryxdDPUBtA
widget/windows/GfxInfo.cpp
--- a/widget/windows/GfxInfo.cpp
+++ b/widget/windows/GfxInfo.cpp
@@ -445,21 +445,24 @@ GfxInfo::Init()
   uint32_t adapterVendorID[2] = {0, 0};
   uint32_t adapterDeviceID[2] = {0, 0};
   uint32_t adapterSubsysID[2] = {0, 0};
 
   adapterVendorID[0] = ParseIDFromDeviceID(mDeviceID[0], "VEN_", 4);
   adapterDeviceID[0] = ParseIDFromDeviceID(mDeviceID[0], "&DEV_", 4);
   adapterSubsysID[0] = ParseIDFromDeviceID(mDeviceID[0],  "&SUBSYS_", 8);
 
-  mAdapterVendorID[0].AppendPrintf("0x%04x", adapterVendorID[0]);
-  mAdapterDeviceID[0].AppendPrintf("0x%04x", adapterDeviceID[0]);
-  mAdapterSubsysID[0].AppendPrintf("%08x", adapterSubsysID[0]);
+  // Sometimes we don't get the valid device using this method.  For now,
+  // allow zero vendor or device as valid, as long as the other value is
+  // non-zero.
+  bool foundValidDevice = (adapterVendorID[0] != 0 ||
+                           adapterDeviceID[0] != 0);
 
-  // We now check for second display adapter.
+  // We now check for second display adapter.  If we didn't find the valid
+  // device using the original approach, we will try the alternative.
 
   // Device interface class for display adapters.
   CLSID GUID_DISPLAY_DEVICE_ARRIVAL;
   HRESULT hresult = CLSIDFromString(L"{1CA05180-A699-450A-9A0C-DE4FBE3DDD89}",
                                &GUID_DISPLAY_DEVICE_ARRIVAL);
   if (hresult == NOERROR) {
     devinfo = SetupDiGetClassDevsW(&GUID_DISPLAY_DEVICE_ARRIVAL,
                                    nullptr, nullptr,
@@ -498,18 +501,21 @@ GfxInfo::Init()
             result = RegQueryValueExW(key, L"MatchingDeviceId", nullptr,
                                       nullptr, (LPBYTE)value, &dwcbData);
             if (result != ERROR_SUCCESS) {
               continue;
             }
             deviceID2 = value;
             adapterVendorID[1] = ParseIDFromDeviceID(deviceID2, "VEN_", 4);
             adapterDeviceID[1] = ParseIDFromDeviceID(deviceID2, "&DEV_", 4);
-            if (adapterVendorID[0] == adapterVendorID[1] &&
-                adapterDeviceID[0] == adapterDeviceID[1]) {
+            // Skip the devices we already considered, as well as any
+            // "zero" ones.
+            if ((adapterVendorID[0] == adapterVendorID[1] &&
+                 adapterDeviceID[0] == adapterDeviceID[1]) ||
+                (adapterVendorID[1] == 0 && adapterDeviceID[1] == 0)) {
               RegCloseKey(key);
               continue;
             }
 
             // If this device is missing driver information, it is unlikely to
             // be a real display adapter.
             if (NS_FAILED(GetKeyValue(driverKey2.get(), L"InstalledDisplayDrivers",
                            adapterDriver2, REG_MULTI_SZ))) {
@@ -537,16 +543,31 @@ GfxInfo::Init()
                                       nullptr, (LPBYTE)value, &dwcbData);
             if (result != ERROR_SUCCESS) {
               dwcbData = sizeof(value);
               result = RegQueryValueExW(key, L"DriverDesc", nullptr, nullptr,
                                         (LPBYTE)value, &dwcbData);
             }
             RegCloseKey(key);
             if (result == ERROR_SUCCESS) {
+              // If we didn't find a valid device with the original method
+              // take this one, and continue looking for the second GPU.
+              if (!foundValidDevice) {
+                foundValidDevice = true;
+                adapterVendorID[0] = adapterVendorID[1];
+                adapterDeviceID[0] = adapterDeviceID[1];
+                mDeviceString[0] = value;
+                mDeviceID[0] = deviceID2;
+                mDeviceKey[0] = driverKey2;
+                mDriverVersion[0] = driverVersion2;
+                mDriverDate[0] = driverDate2;
+                adapterSubsysID[0] = ParseIDFromDeviceID(mDeviceID[0], "&SUBSYS_", 8);
+                continue;
+              }
+
               mHasDualGPU = true;
               mDeviceString[1] = value;
               mDeviceID[1] = deviceID2;
               mDeviceKey[1] = driverKey2;
               mDriverVersion[1] = driverVersion2;
               mDriverDate[1] = driverDate2;
               adapterSubsysID[1] = ParseIDFromDeviceID(mDeviceID[1], "&SUBSYS_", 8);
               mAdapterVendorID[1].AppendPrintf("0x%04x", adapterVendorID[1]);
@@ -557,16 +578,20 @@ GfxInfo::Init()
           }
         }
       }
 
       SetupDiDestroyDeviceInfoList(devinfo);
     }
   }
 
+  mAdapterVendorID[0].AppendPrintf("0x%04x", adapterVendorID[0]);
+  mAdapterDeviceID[0].AppendPrintf("0x%04x", adapterDeviceID[0]);
+  mAdapterSubsysID[0].AppendPrintf("%08x", adapterSubsysID[0]);
+
   // Sometimes, the enumeration is not quite right and the two adapters
   // end up being swapped.  Actually enumerate the adapters that come
   // back from the DXGI factory to check, and tag the second as active
   // if found.
   if (mHasDualGPU) {
     nsModuleHandle dxgiModule(LoadLibrarySystem32(L"dxgi.dll"));
     decltype(CreateDXGIFactory)* createDXGIFactory = (decltype(CreateDXGIFactory)*)
       GetProcAddress(dxgiModule, "CreateDXGIFactory");