Merge mozilla-beta to b2g34. a=merge
[gecko.git] / widget / windows / GfxInfo.cpp
blob95421de31c8025663df2fd00d0613cb85db2fcfc
1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* This Source Code Form is subject to the terms of the Mozilla Public
3 * License, v. 2.0. If a copy of the MPL was not distributed with this
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6 #include "mozilla/ArrayUtils.h"
8 #include <windows.h>
9 #include <setupapi.h>
10 #include "gfxWindowsPlatform.h"
11 #include "GfxInfo.h"
12 #include "GfxInfoWebGL.h"
13 #include "nsUnicharUtils.h"
14 #include "prenv.h"
15 #include "prprf.h"
16 #include "GfxDriverInfo.h"
17 #include "mozilla/Preferences.h"
18 #include "nsPrintfCString.h"
20 #if defined(MOZ_CRASHREPORTER)
21 #include "nsExceptionHandler.h"
22 #include "nsICrashReporter.h"
23 #define NS_CRASHREPORTER_CONTRACTID "@mozilla.org/toolkit/crash-reporter;1"
24 #endif
26 using namespace mozilla;
27 using namespace mozilla::widget;
29 #ifdef DEBUG
30 NS_IMPL_ISUPPORTS_INHERITED(GfxInfo, GfxInfoBase, nsIGfxInfoDebug)
31 #endif
33 static const uint32_t allWindowsVersions = 0xffffffff;
35 GfxInfo::GfxInfo()
36 : mWindowsVersion(0),
37 mHasDualGPU(false),
38 mIsGPU2Active(false)
42 /* GetD2DEnabled and GetDwriteEnabled shouldn't be called until after gfxPlatform initialization
43 * has occurred because they depend on it for information. (See bug 591561) */
44 nsresult
45 GfxInfo::GetD2DEnabled(bool *aEnabled)
47 *aEnabled = gfxWindowsPlatform::GetPlatform()->GetRenderMode() == gfxWindowsPlatform::RENDER_DIRECT2D;
48 return NS_OK;
51 nsresult
52 GfxInfo::GetDWriteEnabled(bool *aEnabled)
54 *aEnabled = gfxWindowsPlatform::GetPlatform()->DWriteEnabled();
55 return NS_OK;
58 /* readonly attribute DOMString DWriteVersion; */
59 NS_IMETHODIMP
60 GfxInfo::GetDWriteVersion(nsAString & aDwriteVersion)
62 gfxWindowsPlatform::GetDLLVersion(L"dwrite.dll", aDwriteVersion);
63 return NS_OK;
66 #define PIXEL_STRUCT_RGB 1
67 #define PIXEL_STRUCT_BGR 2
69 /* readonly attribute DOMString cleartypeParameters; */
70 NS_IMETHODIMP
71 GfxInfo::GetCleartypeParameters(nsAString & aCleartypeParams)
73 nsTArray<ClearTypeParameterInfo> clearTypeParams;
75 gfxWindowsPlatform::GetPlatform()->GetCleartypeParams(clearTypeParams);
76 uint32_t d, numDisplays = clearTypeParams.Length();
77 bool displayNames = (numDisplays > 1);
78 bool foundData = false;
79 nsString outStr;
81 for (d = 0; d < numDisplays; d++) {
82 ClearTypeParameterInfo& params = clearTypeParams[d];
84 if (displayNames) {
85 outStr.AppendPrintf("%s [ ", params.displayName.get());
88 if (params.gamma >= 0) {
89 foundData = true;
90 outStr.AppendPrintf("Gamma: %d ", params.gamma);
93 if (params.pixelStructure >= 0) {
94 foundData = true;
95 if (params.pixelStructure == PIXEL_STRUCT_RGB ||
96 params.pixelStructure == PIXEL_STRUCT_BGR)
98 outStr.AppendPrintf("Pixel Structure: %s ",
99 (params.pixelStructure == PIXEL_STRUCT_RGB ?
100 L"RGB" : L"BGR"));
101 } else {
102 outStr.AppendPrintf("Pixel Structure: %d ", params.pixelStructure);
106 if (params.clearTypeLevel >= 0) {
107 foundData = true;
108 outStr.AppendPrintf("ClearType Level: %d ", params.clearTypeLevel);
111 if (params.enhancedContrast >= 0) {
112 foundData = true;
113 outStr.AppendPrintf("Enhanced Contrast: %d ", params.enhancedContrast);
116 if (displayNames) {
117 outStr.Append(MOZ_UTF16("] "));
121 if (foundData) {
122 aCleartypeParams.Assign(outStr);
123 return NS_OK;
125 return NS_ERROR_FAILURE;
128 static nsresult GetKeyValue(const WCHAR* keyLocation, const WCHAR* keyName, nsAString& destString, int type)
130 HKEY key;
131 DWORD dwcbData;
132 DWORD dValue;
133 DWORD resultType;
134 LONG result;
135 nsresult retval = NS_OK;
137 result = RegOpenKeyExW(HKEY_LOCAL_MACHINE, keyLocation, 0, KEY_QUERY_VALUE, &key);
138 if (result != ERROR_SUCCESS) {
139 return NS_ERROR_FAILURE;
142 switch (type) {
143 case REG_DWORD: {
144 // We only use this for vram size
145 dwcbData = sizeof(dValue);
146 result = RegQueryValueExW(key, keyName, nullptr, &resultType,
147 (LPBYTE)&dValue, &dwcbData);
148 if (result == ERROR_SUCCESS && resultType == REG_DWORD) {
149 dValue = dValue / 1024 / 1024;
150 destString.AppendInt(int32_t(dValue));
151 } else {
152 retval = NS_ERROR_FAILURE;
154 break;
156 case REG_MULTI_SZ: {
157 // A chain of null-separated strings; we convert the nulls to spaces
158 WCHAR wCharValue[1024];
159 dwcbData = sizeof(wCharValue);
161 result = RegQueryValueExW(key, keyName, nullptr, &resultType,
162 (LPBYTE)wCharValue, &dwcbData);
163 if (result == ERROR_SUCCESS && resultType == REG_MULTI_SZ) {
164 // This bit here could probably be cleaner.
165 bool isValid = false;
167 DWORD strLen = dwcbData/sizeof(wCharValue[0]);
168 for (DWORD i = 0; i < strLen; i++) {
169 if (wCharValue[i] == '\0') {
170 if (i < strLen - 1 && wCharValue[i + 1] == '\0') {
171 isValid = true;
172 break;
173 } else {
174 wCharValue[i] = ' ';
179 // ensure wCharValue is null terminated
180 wCharValue[strLen-1] = '\0';
182 if (isValid)
183 destString = wCharValue;
185 } else {
186 retval = NS_ERROR_FAILURE;
189 break;
192 RegCloseKey(key);
194 return retval;
197 // The driver ID is a string like PCI\VEN_15AD&DEV_0405&SUBSYS_040515AD, possibly
198 // followed by &REV_XXXX. We uppercase the string, and strip the &REV_ part
199 // from it, if found.
200 static void normalizeDriverId(nsString& driverid) {
201 ToUpperCase(driverid);
202 int32_t rev = driverid.Find(NS_LITERAL_CSTRING("&REV_"));
203 if (rev != -1) {
204 driverid.Cut(rev, driverid.Length());
208 // The device ID is a string like PCI\VEN_15AD&DEV_0405&SUBSYS_040515AD
209 // this function is used to extract the id's out of it
210 uint32_t
211 ParseIDFromDeviceID(const nsAString &key, const char *prefix, int length)
213 nsAutoString id(key);
214 ToUpperCase(id);
215 int32_t start = id.Find(prefix);
216 if (start != -1) {
217 id.Cut(0, start + strlen(prefix));
218 id.Truncate(length);
220 nsresult err;
221 return id.ToInteger(&err, 16);
224 // OS version in 16.16 major/minor form
225 // based on http://msdn.microsoft.com/en-us/library/ms724834(VS.85).aspx
226 enum {
227 kWindowsUnknown = 0,
228 kWindowsXP = 0x50001,
229 kWindowsServer2003 = 0x50002,
230 kWindowsVista = 0x60000,
231 kWindows7 = 0x60001,
232 kWindows8 = 0x60002,
233 kWindows8_1 = 0x60003
236 static int32_t
237 WindowsOSVersion()
239 static int32_t winVersion = UNINITIALIZED_VALUE;
241 OSVERSIONINFO vinfo;
243 if (winVersion == UNINITIALIZED_VALUE) {
244 vinfo.dwOSVersionInfoSize = sizeof (vinfo);
245 #pragma warning(push)
246 #pragma warning(disable:4996)
247 if (!GetVersionEx(&vinfo)) {
248 #pragma warning(pop)
249 winVersion = kWindowsUnknown;
250 } else {
251 winVersion = int32_t(vinfo.dwMajorVersion << 16) + vinfo.dwMinorVersion;
255 return winVersion;
258 /* Other interesting places for info:
259 * IDXGIAdapter::GetDesc()
260 * IDirectDraw7::GetAvailableVidMem()
261 * e->GetAvailableTextureMem()
262 * */
264 #define DEVICE_KEY_PREFIX L"\\Registry\\Machine\\"
265 nsresult
266 GfxInfo::Init()
268 nsresult rv = GfxInfoBase::Init();
270 DISPLAY_DEVICEW displayDevice;
271 displayDevice.cb = sizeof(displayDevice);
272 int deviceIndex = 0;
274 const char *spoofedWindowsVersion = PR_GetEnv("MOZ_GFX_SPOOF_WINDOWS_VERSION");
275 if (spoofedWindowsVersion) {
276 PR_sscanf(spoofedWindowsVersion, "%x", &mWindowsVersion);
277 } else {
278 mWindowsVersion = WindowsOSVersion();
281 mDeviceKeyDebug = NS_LITERAL_STRING("PrimarySearch");
283 while (EnumDisplayDevicesW(nullptr, deviceIndex, &displayDevice, 0)) {
284 if (displayDevice.StateFlags & DISPLAY_DEVICE_PRIMARY_DEVICE) {
285 mDeviceKeyDebug = NS_LITERAL_STRING("NullSearch");
286 break;
288 deviceIndex++;
291 // make sure the string is nullptr terminated
292 if (wcsnlen(displayDevice.DeviceKey, ArrayLength(displayDevice.DeviceKey))
293 == ArrayLength(displayDevice.DeviceKey)) {
294 // we did not find a nullptr
295 return rv;
298 mDeviceKeyDebug = displayDevice.DeviceKey;
300 /* DeviceKey is "reserved" according to MSDN so we'll be careful with it */
301 /* check that DeviceKey begins with DEVICE_KEY_PREFIX */
302 /* some systems have a DeviceKey starting with \REGISTRY\Machine\ so we need to compare case insenstively */
303 if (_wcsnicmp(displayDevice.DeviceKey, DEVICE_KEY_PREFIX, ArrayLength(DEVICE_KEY_PREFIX)-1) != 0)
304 return rv;
306 // chop off DEVICE_KEY_PREFIX
307 mDeviceKey = displayDevice.DeviceKey + ArrayLength(DEVICE_KEY_PREFIX)-1;
309 mDeviceID = displayDevice.DeviceID;
310 mDeviceString = displayDevice.DeviceString;
312 // On Windows 8 and Server 2012 hosts, we want to not block RDP
313 // sessions from attempting hardware acceleration. RemoteFX
314 // provides features and functionaltiy that can give a good D3D10 +
315 // D2D + DirectWrite experience emulated via a software GPU.
317 // Unfortunately, the Device ID is nullptr, and we can't enumerate
318 // it using the setup infrastructure (SetupDiGetClassDevsW below
319 // will return INVALID_HANDLE_VALUE).
320 if (mWindowsVersion == kWindows8 &&
321 mDeviceID.Length() == 0 &&
322 mDeviceString.EqualsLiteral("RDPUDD Chained DD"))
324 WCHAR sysdir[255];
325 UINT len = GetSystemDirectory(sysdir, sizeof(sysdir));
326 if (len < sizeof(sysdir)) {
327 nsString rdpudd(sysdir);
328 rdpudd.AppendLiteral("\\rdpudd.dll");
329 gfxWindowsPlatform::GetDLLVersion(rdpudd.BeginReading(), mDriverVersion);
330 mDriverDate.AssignLiteral("01-01-1970");
332 // 0x1414 is Microsoft; 0xfefe is an invented (and unused) code
333 mDeviceID.AssignLiteral("PCI\\VEN_1414&DEV_FEFE&SUBSYS_00000000");
337 /* create a device information set composed of the current display device */
338 HDEVINFO devinfo = SetupDiGetClassDevsW(nullptr, mDeviceID.get(), nullptr,
339 DIGCF_PRESENT | DIGCF_PROFILE | DIGCF_ALLCLASSES);
341 if (devinfo != INVALID_HANDLE_VALUE) {
342 HKEY key;
343 LONG result;
344 WCHAR value[255];
345 DWORD dwcbData;
346 SP_DEVINFO_DATA devinfoData;
347 DWORD memberIndex = 0;
349 devinfoData.cbSize = sizeof(devinfoData);
350 NS_NAMED_LITERAL_STRING(driverKeyPre, "System\\CurrentControlSet\\Control\\Class\\");
351 /* enumerate device information elements in the device information set */
352 while (SetupDiEnumDeviceInfo(devinfo, memberIndex++, &devinfoData)) {
353 /* get a string that identifies the device's driver key */
354 if (SetupDiGetDeviceRegistryPropertyW(devinfo,
355 &devinfoData,
356 SPDRP_DRIVER,
357 nullptr,
358 (PBYTE)value,
359 sizeof(value),
360 nullptr)) {
361 nsAutoString driverKey(driverKeyPre);
362 driverKey += value;
363 result = RegOpenKeyExW(HKEY_LOCAL_MACHINE, driverKey.get(), 0, KEY_QUERY_VALUE, &key);
364 if (result == ERROR_SUCCESS) {
365 /* we've found the driver we're looking for */
366 dwcbData = sizeof(value);
367 result = RegQueryValueExW(key, L"DriverVersion", nullptr, nullptr,
368 (LPBYTE)value, &dwcbData);
369 if (result == ERROR_SUCCESS) {
370 mDriverVersion = value;
371 } else {
372 // If the entry wasn't found, assume the worst (0.0.0.0).
373 mDriverVersion.AssignLiteral("0.0.0.0");
375 dwcbData = sizeof(value);
376 result = RegQueryValueExW(key, L"DriverDate", nullptr, nullptr,
377 (LPBYTE)value, &dwcbData);
378 if (result == ERROR_SUCCESS) {
379 mDriverDate = value;
380 } else {
381 // Again, assume the worst
382 mDriverDate.AssignLiteral("01-01-1970");
384 RegCloseKey(key);
385 break;
390 SetupDiDestroyDeviceInfoList(devinfo);
393 mAdapterVendorID.AppendPrintf("0x%04x", ParseIDFromDeviceID(mDeviceID, "VEN_", 4));
394 mAdapterDeviceID.AppendPrintf("0x%04x", ParseIDFromDeviceID(mDeviceID, "&DEV_", 4));
395 mAdapterSubsysID.AppendPrintf("%08x", ParseIDFromDeviceID(mDeviceID, "&SUBSYS_", 8));
397 // We now check for second display adapter.
399 // Device interface class for display adapters.
400 CLSID GUID_DISPLAY_DEVICE_ARRIVAL;
401 HRESULT hresult = CLSIDFromString(L"{1CA05180-A699-450A-9A0C-DE4FBE3DDD89}",
402 &GUID_DISPLAY_DEVICE_ARRIVAL);
403 if (hresult == NOERROR) {
404 devinfo = SetupDiGetClassDevsW(&GUID_DISPLAY_DEVICE_ARRIVAL,
405 nullptr, nullptr,
406 DIGCF_PRESENT | DIGCF_INTERFACEDEVICE);
408 if (devinfo != INVALID_HANDLE_VALUE) {
409 HKEY key;
410 LONG result;
411 WCHAR value[255];
412 DWORD dwcbData;
413 SP_DEVINFO_DATA devinfoData;
414 DWORD memberIndex = 0;
415 devinfoData.cbSize = sizeof(devinfoData);
417 nsAutoString adapterDriver2;
418 nsAutoString deviceID2;
419 nsAutoString driverVersion2;
420 nsAutoString driverDate2;
421 uint32_t adapterVendorID2;
422 uint32_t adapterDeviceID2;
424 NS_NAMED_LITERAL_STRING(driverKeyPre, "System\\CurrentControlSet\\Control\\Class\\");
425 /* enumerate device information elements in the device information set */
426 while (SetupDiEnumDeviceInfo(devinfo, memberIndex++, &devinfoData)) {
427 /* get a string that identifies the device's driver key */
428 if (SetupDiGetDeviceRegistryPropertyW(devinfo,
429 &devinfoData,
430 SPDRP_DRIVER,
431 nullptr,
432 (PBYTE)value,
433 sizeof(value),
434 nullptr)) {
435 nsAutoString driverKey2(driverKeyPre);
436 driverKey2 += value;
437 result = RegOpenKeyExW(HKEY_LOCAL_MACHINE, driverKey2.get(), 0, KEY_QUERY_VALUE, &key);
438 if (result == ERROR_SUCCESS) {
439 dwcbData = sizeof(value);
440 result = RegQueryValueExW(key, L"MatchingDeviceId", nullptr,
441 nullptr, (LPBYTE)value, &dwcbData);
442 if (result != ERROR_SUCCESS) {
443 continue;
445 deviceID2 = value;
446 nsAutoString adapterVendorID2String;
447 nsAutoString adapterDeviceID2String;
448 adapterVendorID2 = ParseIDFromDeviceID(deviceID2, "VEN_", 4);
449 adapterVendorID2String.AppendPrintf("0x%04x", adapterVendorID2);
450 adapterDeviceID2 = ParseIDFromDeviceID(deviceID2, "&DEV_", 4);
451 adapterDeviceID2String.AppendPrintf("0x%04x", adapterDeviceID2);
452 if (mAdapterVendorID == adapterVendorID2String &&
453 mAdapterDeviceID == adapterDeviceID2String) {
454 RegCloseKey(key);
455 continue;
458 // If this device is missing driver information, it is unlikely to
459 // be a real display adapter.
460 if (NS_FAILED(GetKeyValue(driverKey2.get(), L"InstalledDisplayDrivers",
461 adapterDriver2, REG_MULTI_SZ))) {
462 RegCloseKey(key);
463 continue;
465 dwcbData = sizeof(value);
466 result = RegQueryValueExW(key, L"DriverVersion", nullptr, nullptr,
467 (LPBYTE)value, &dwcbData);
468 if (result != ERROR_SUCCESS) {
469 RegCloseKey(key);
470 continue;
472 driverVersion2 = value;
473 dwcbData = sizeof(value);
474 result = RegQueryValueExW(key, L"DriverDate", nullptr, nullptr,
475 (LPBYTE)value, &dwcbData);
476 if (result != ERROR_SUCCESS) {
477 RegCloseKey(key);
478 continue;
480 driverDate2 = value;
481 dwcbData = sizeof(value);
482 result = RegQueryValueExW(key, L"Device Description", nullptr,
483 nullptr, (LPBYTE)value, &dwcbData);
484 if (result != ERROR_SUCCESS) {
485 dwcbData = sizeof(value);
486 result = RegQueryValueExW(key, L"DriverDesc", nullptr, nullptr,
487 (LPBYTE)value, &dwcbData);
489 RegCloseKey(key);
490 if (result == ERROR_SUCCESS) {
491 mHasDualGPU = true;
492 mDeviceString2 = value;
493 mDeviceID2 = deviceID2;
494 mDeviceKey2 = driverKey2;
495 mDriverVersion2 = driverVersion2;
496 mDriverDate2 = driverDate2;
497 mAdapterVendorID2.AppendPrintf("0x%04x", adapterVendorID2);
498 mAdapterDeviceID2.AppendPrintf("0x%04x", adapterDeviceID2);
499 mAdapterSubsysID2.AppendPrintf("%08x", ParseIDFromDeviceID(mDeviceID2, "&SUBSYS_", 8));
500 break;
506 SetupDiDestroyDeviceInfoList(devinfo);
510 mHasDriverVersionMismatch = false;
511 if (mAdapterVendorID == GfxDriverInfo::GetDeviceVendor(VendorIntel)) {
512 // we've had big crashers (bugs 590373 and 595364) apparently correlated
513 // with bad Intel driver installations where the DriverVersion reported
514 // by the registry was not the version of the DLL.
515 bool is64bitApp = sizeof(void*) == 8;
516 const char16_t *dllFileName = is64bitApp
517 ? MOZ_UTF16("igd10umd64.dll")
518 : MOZ_UTF16("igd10umd32.dll"),
519 *dllFileName2 = is64bitApp
520 ? MOZ_UTF16("igd10iumd64.dll")
521 : MOZ_UTF16("igd10iumd32.dll");
522 nsString dllVersion, dllVersion2;
523 gfxWindowsPlatform::GetDLLVersion((char16_t*)dllFileName, dllVersion);
524 gfxWindowsPlatform::GetDLLVersion((char16_t*)dllFileName2, dllVersion2);
526 uint64_t dllNumericVersion = 0, dllNumericVersion2 = 0,
527 driverNumericVersion = 0, knownSafeMismatchVersion = 0;
528 ParseDriverVersion(dllVersion, &dllNumericVersion);
529 ParseDriverVersion(dllVersion2, &dllNumericVersion2);
530 ParseDriverVersion(mDriverVersion, &driverNumericVersion);
531 ParseDriverVersion(NS_LITERAL_STRING("9.17.10.0"), &knownSafeMismatchVersion);
533 // If there's a driver version mismatch, consider this harmful only when
534 // the driver version is less than knownSafeMismatchVersion. See the
535 // above comment about crashes with old mismatches. If the GetDllVersion
536 // call fails, then they return 0, so that will be considered a mismatch.
537 if (dllNumericVersion != driverNumericVersion &&
538 dllNumericVersion2 != driverNumericVersion &&
539 (driverNumericVersion < knownSafeMismatchVersion ||
540 std::max(dllNumericVersion, dllNumericVersion2) < knownSafeMismatchVersion)) {
541 mHasDriverVersionMismatch = true;
545 const char *spoofedDriverVersionString = PR_GetEnv("MOZ_GFX_SPOOF_DRIVER_VERSION");
546 if (spoofedDriverVersionString) {
547 mDriverVersion.AssignASCII(spoofedDriverVersionString);
550 const char *spoofedVendor = PR_GetEnv("MOZ_GFX_SPOOF_VENDOR_ID");
551 if (spoofedVendor) {
552 mAdapterVendorID.AssignASCII(spoofedVendor);
555 const char *spoofedDevice = PR_GetEnv("MOZ_GFX_SPOOF_DEVICE_ID");
556 if (spoofedDevice) {
557 mAdapterDeviceID.AssignASCII(spoofedDevice);
560 AddCrashReportAnnotations();
562 return rv;
565 /* readonly attribute DOMString adapterDescription; */
566 NS_IMETHODIMP
567 GfxInfo::GetAdapterDescription(nsAString & aAdapterDescription)
569 aAdapterDescription = mDeviceString;
570 return NS_OK;
573 /* readonly attribute DOMString adapterDescription2; */
574 NS_IMETHODIMP
575 GfxInfo::GetAdapterDescription2(nsAString & aAdapterDescription)
577 aAdapterDescription = mDeviceString2;
578 return NS_OK;
581 /* readonly attribute DOMString adapterRAM; */
582 NS_IMETHODIMP
583 GfxInfo::GetAdapterRAM(nsAString & aAdapterRAM)
585 if (NS_FAILED(GetKeyValue(mDeviceKey.get(), L"HardwareInformation.MemorySize", aAdapterRAM, REG_DWORD)))
586 aAdapterRAM = L"Unknown";
587 return NS_OK;
590 /* readonly attribute DOMString adapterRAM2; */
591 NS_IMETHODIMP
592 GfxInfo::GetAdapterRAM2(nsAString & aAdapterRAM)
594 if (!mHasDualGPU) {
595 aAdapterRAM.Truncate();
596 } else if (NS_FAILED(GetKeyValue(mDeviceKey2.get(), L"HardwareInformation.MemorySize", aAdapterRAM, REG_DWORD))) {
597 aAdapterRAM = L"Unknown";
599 return NS_OK;
602 /* readonly attribute DOMString adapterDriver; */
603 NS_IMETHODIMP
604 GfxInfo::GetAdapterDriver(nsAString & aAdapterDriver)
606 if (NS_FAILED(GetKeyValue(mDeviceKey.get(), L"InstalledDisplayDrivers", aAdapterDriver, REG_MULTI_SZ)))
607 aAdapterDriver = L"Unknown";
608 return NS_OK;
611 /* readonly attribute DOMString adapterDriver2; */
612 NS_IMETHODIMP
613 GfxInfo::GetAdapterDriver2(nsAString & aAdapterDriver)
615 if (!mHasDualGPU) {
616 aAdapterDriver.Truncate();
617 } else if (NS_FAILED(GetKeyValue(mDeviceKey2.get(), L"InstalledDisplayDrivers", aAdapterDriver, REG_MULTI_SZ))) {
618 aAdapterDriver = L"Unknown";
620 return NS_OK;
623 /* readonly attribute DOMString adapterDriverVersion; */
624 NS_IMETHODIMP
625 GfxInfo::GetAdapterDriverVersion(nsAString & aAdapterDriverVersion)
627 aAdapterDriverVersion = mDriverVersion;
628 return NS_OK;
631 /* readonly attribute DOMString adapterDriverDate; */
632 NS_IMETHODIMP
633 GfxInfo::GetAdapterDriverDate(nsAString & aAdapterDriverDate)
635 aAdapterDriverDate = mDriverDate;
636 return NS_OK;
639 /* readonly attribute DOMString adapterDriverVersion2; */
640 NS_IMETHODIMP
641 GfxInfo::GetAdapterDriverVersion2(nsAString & aAdapterDriverVersion)
643 aAdapterDriverVersion = mDriverVersion2;
644 return NS_OK;
647 /* readonly attribute DOMString adapterDriverDate2; */
648 NS_IMETHODIMP
649 GfxInfo::GetAdapterDriverDate2(nsAString & aAdapterDriverDate)
651 aAdapterDriverDate = mDriverDate2;
652 return NS_OK;
655 /* readonly attribute DOMString adapterVendorID; */
656 NS_IMETHODIMP
657 GfxInfo::GetAdapterVendorID(nsAString & aAdapterVendorID)
659 aAdapterVendorID = mAdapterVendorID;
660 return NS_OK;
663 /* readonly attribute DOMString adapterVendorID2; */
664 NS_IMETHODIMP
665 GfxInfo::GetAdapterVendorID2(nsAString & aAdapterVendorID)
667 aAdapterVendorID = mAdapterVendorID2;
668 return NS_OK;
671 /* readonly attribute DOMString adapterDeviceID; */
672 NS_IMETHODIMP
673 GfxInfo::GetAdapterDeviceID(nsAString & aAdapterDeviceID)
675 aAdapterDeviceID = mAdapterDeviceID;
676 return NS_OK;
679 /* readonly attribute DOMString adapterDeviceID2; */
680 NS_IMETHODIMP
681 GfxInfo::GetAdapterDeviceID2(nsAString & aAdapterDeviceID)
683 aAdapterDeviceID = mAdapterDeviceID2;
684 return NS_OK;
687 /* readonly attribute DOMString adapterSubsysID; */
688 NS_IMETHODIMP
689 GfxInfo::GetAdapterSubsysID(nsAString & aAdapterSubsysID)
691 aAdapterSubsysID = mAdapterSubsysID;
692 return NS_OK;
695 /* readonly attribute DOMString adapterSubsysID2; */
696 NS_IMETHODIMP
697 GfxInfo::GetAdapterSubsysID2(nsAString & aAdapterSubsysID)
699 aAdapterSubsysID = mAdapterSubsysID2;
700 return NS_OK;
703 /* readonly attribute boolean isGPU2Active; */
704 NS_IMETHODIMP
705 GfxInfo::GetIsGPU2Active(bool* aIsGPU2Active)
707 *aIsGPU2Active = mIsGPU2Active;
708 return NS_OK;
711 #if defined(MOZ_CRASHREPORTER)
712 /* Cisco's VPN software can cause corruption of the floating point state.
713 * Make a note of this in our crash reports so that some weird crashes
714 * make more sense */
715 static void
716 CheckForCiscoVPN() {
717 LONG result;
718 HKEY key;
719 /* This will give false positives, but hopefully no false negatives */
720 result = RegOpenKeyExW(HKEY_LOCAL_MACHINE, L"Software\\Cisco Systems\\VPN Client", 0, KEY_QUERY_VALUE, &key);
721 if (result == ERROR_SUCCESS) {
722 RegCloseKey(key);
723 CrashReporter::AppendAppNotesToCrashReport(NS_LITERAL_CSTRING("Cisco VPN\n"));
726 #endif
728 void
729 GfxInfo::AddCrashReportAnnotations()
731 #if defined(MOZ_CRASHREPORTER)
732 CheckForCiscoVPN();
734 if (mHasDriverVersionMismatch) {
735 CrashReporter::AppendAppNotesToCrashReport(NS_LITERAL_CSTRING("DriverVersionMismatch\n"));
738 nsString deviceID, vendorID, driverVersion, subsysID;
739 nsCString narrowDeviceID, narrowVendorID, narrowDriverVersion, narrowSubsysID;
741 GetAdapterDeviceID(deviceID);
742 CopyUTF16toUTF8(deviceID, narrowDeviceID);
743 GetAdapterVendorID(vendorID);
744 CopyUTF16toUTF8(vendorID, narrowVendorID);
745 GetAdapterDriverVersion(driverVersion);
746 CopyUTF16toUTF8(driverVersion, narrowDriverVersion);
747 GetAdapterSubsysID(subsysID);
748 CopyUTF16toUTF8(subsysID, narrowSubsysID);
750 CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("AdapterVendorID"),
751 narrowVendorID);
752 CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("AdapterDeviceID"),
753 narrowDeviceID);
754 CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("AdapterDriverVersion"),
755 narrowDriverVersion);
756 CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("AdapterSubsysID"),
757 narrowSubsysID);
759 /* Add an App Note for now so that we get the data immediately. These
760 * can go away after we store the above in the socorro db */
761 nsAutoCString note;
762 /* AppendPrintf only supports 32 character strings, mrghh. */
763 note.AppendLiteral("AdapterVendorID: ");
764 note.Append(narrowVendorID);
765 note.AppendLiteral(", AdapterDeviceID: ");
766 note.Append(narrowDeviceID);
767 note.AppendLiteral(", AdapterSubsysID: ");
768 note.Append(narrowSubsysID);
769 note.AppendLiteral(", AdapterDriverVersion: ");
770 note.Append(NS_LossyConvertUTF16toASCII(driverVersion));
772 if (vendorID == GfxDriverInfo::GetDeviceVendor(VendorAll)) {
773 /* if we didn't find a valid vendorID lets append the mDeviceID string to try to find out why */
774 note.AppendLiteral(", ");
775 LossyAppendUTF16toASCII(mDeviceID, note);
776 note.AppendLiteral(", ");
777 LossyAppendUTF16toASCII(mDeviceKeyDebug, note);
778 LossyAppendUTF16toASCII(mDeviceKeyDebug, note);
780 note.Append("\n");
782 if (mHasDualGPU) {
783 nsString deviceID2, vendorID2, subsysID2;
784 nsAutoString adapterDriverVersionString2;
785 nsCString narrowDeviceID2, narrowVendorID2, narrowSubsysID2;
787 note.AppendLiteral("Has dual GPUs. GPU #2: ");
788 GetAdapterDeviceID2(deviceID2);
789 CopyUTF16toUTF8(deviceID2, narrowDeviceID2);
790 GetAdapterVendorID2(vendorID2);
791 CopyUTF16toUTF8(vendorID2, narrowVendorID2);
792 GetAdapterDriverVersion2(adapterDriverVersionString2);
793 GetAdapterSubsysID(subsysID2);
794 CopyUTF16toUTF8(subsysID2, narrowSubsysID2);
795 note.AppendLiteral("AdapterVendorID2: ");
796 note.Append(narrowVendorID2);
797 note.AppendLiteral(", AdapterDeviceID2: ");
798 note.Append(narrowDeviceID2);
799 note.AppendLiteral(", AdapterSubsysID2: ");
800 note.Append(narrowSubsysID2);
801 note.AppendLiteral(", AdapterDriverVersion2: ");
802 note.Append(NS_LossyConvertUTF16toASCII(adapterDriverVersionString2));
804 CrashReporter::AppendAppNotesToCrashReport(note);
806 #endif
809 static OperatingSystem
810 WindowsVersionToOperatingSystem(int32_t aWindowsVersion)
812 switch(aWindowsVersion) {
813 case kWindowsXP:
814 return DRIVER_OS_WINDOWS_XP;
815 case kWindowsServer2003:
816 return DRIVER_OS_WINDOWS_SERVER_2003;
817 case kWindowsVista:
818 return DRIVER_OS_WINDOWS_VISTA;
819 case kWindows7:
820 return DRIVER_OS_WINDOWS_7;
821 case kWindows8:
822 return DRIVER_OS_WINDOWS_8;
823 case kWindows8_1:
824 return DRIVER_OS_WINDOWS_8_1;
825 case kWindowsUnknown:
826 default:
827 return DRIVER_OS_UNKNOWN;
831 const nsTArray<GfxDriverInfo>&
832 GfxInfo::GetGfxDriverInfo()
834 if (!mDriverInfo->Length()) {
836 * It should be noted here that more specialized rules on certain features
837 * should be inserted -before- more generalized restriction. As the first
838 * match for feature/OS/device found in the list will be used for the final
839 * blacklisting call.
843 * NVIDIA entries
845 APPEND_TO_DRIVER_BLOCKLIST( DRIVER_OS_WINDOWS_XP,
846 (nsAString&) GfxDriverInfo::GetDeviceVendor(VendorNVIDIA), GfxDriverInfo::allDevices,
847 GfxDriverInfo::allFeatures, nsIGfxInfo::FEATURE_BLOCKED_DRIVER_VERSION,
848 DRIVER_LESS_THAN, V(6,14,11,8265), "182.65" );
849 APPEND_TO_DRIVER_BLOCKLIST( DRIVER_OS_WINDOWS_VISTA,
850 (nsAString&) GfxDriverInfo::GetDeviceVendor(VendorNVIDIA), GfxDriverInfo::allDevices,
851 GfxDriverInfo::allFeatures, nsIGfxInfo::FEATURE_BLOCKED_DRIVER_VERSION,
852 DRIVER_LESS_THAN, V(8,17,11,8265), "182.65" );
853 APPEND_TO_DRIVER_BLOCKLIST( DRIVER_OS_WINDOWS_7,
854 (nsAString&) GfxDriverInfo::GetDeviceVendor(VendorNVIDIA), GfxDriverInfo::allDevices,
855 GfxDriverInfo::allFeatures, nsIGfxInfo::FEATURE_BLOCKED_DRIVER_VERSION,
856 DRIVER_LESS_THAN, V(8,17,11,8265), "182.65" );
859 * AMD/ATI entries
861 APPEND_TO_DRIVER_BLOCKLIST( DRIVER_OS_ALL,
862 (nsAString&) GfxDriverInfo::GetDeviceVendor(VendorATI), GfxDriverInfo::allDevices,
863 GfxDriverInfo::allFeatures, nsIGfxInfo::FEATURE_BLOCKED_DRIVER_VERSION,
864 DRIVER_LESS_THAN, V(8,62,0,0), "9.6" );
865 APPEND_TO_DRIVER_BLOCKLIST( DRIVER_OS_ALL,
866 (nsAString&) GfxDriverInfo::GetDeviceVendor(VendorAMD), GfxDriverInfo::allDevices,
867 GfxDriverInfo::allFeatures, nsIGfxInfo::FEATURE_BLOCKED_DRIVER_VERSION,
868 DRIVER_LESS_THAN, V(8,62,0,0), "9.6" );
871 * Bug 783517 - crashes in AMD driver on Windows 8
873 APPEND_TO_DRIVER_BLOCKLIST_RANGE( DRIVER_OS_WINDOWS_8,
874 (nsAString&) GfxDriverInfo::GetDeviceVendor(VendorATI), GfxDriverInfo::allDevices,
875 GfxDriverInfo::allFeatures, nsIGfxInfo::FEATURE_BLOCKED_DRIVER_VERSION,
876 DRIVER_BETWEEN_INCLUSIVE_START, V(8,982,0,0), V(8,983,0,0), "!= 8.982.*.*" );
877 APPEND_TO_DRIVER_BLOCKLIST_RANGE( DRIVER_OS_WINDOWS_8,
878 (nsAString&) GfxDriverInfo::GetDeviceVendor(VendorAMD), GfxDriverInfo::allDevices,
879 GfxDriverInfo::allFeatures, nsIGfxInfo::FEATURE_BLOCKED_DRIVER_VERSION,
880 DRIVER_BETWEEN_INCLUSIVE_START, V(8,982,0,0), V(8,983,0,0), "!= 8.982.*.*" );
882 /* OpenGL on any ATI/AMD hardware is discouraged
883 * See:
884 * bug 619773 - WebGL: Crash with blue screen : "NMI: Parity Check / Memory Parity Error"
885 * bugs 584403, 584404, 620924 - crashes in atioglxx
886 * + many complaints about incorrect rendering
888 APPEND_TO_DRIVER_BLOCKLIST2( DRIVER_OS_ALL,
889 (nsAString&) GfxDriverInfo::GetDeviceVendor(VendorATI), GfxDriverInfo::allDevices,
890 nsIGfxInfo::FEATURE_OPENGL_LAYERS, nsIGfxInfo::FEATURE_DISCOURAGED,
891 DRIVER_LESS_THAN, GfxDriverInfo::allDriverVersions );
892 APPEND_TO_DRIVER_BLOCKLIST2( DRIVER_OS_ALL,
893 (nsAString&) GfxDriverInfo::GetDeviceVendor(VendorATI), GfxDriverInfo::allDevices,
894 nsIGfxInfo::FEATURE_WEBGL_OPENGL, nsIGfxInfo::FEATURE_DISCOURAGED,
895 DRIVER_LESS_THAN, GfxDriverInfo::allDriverVersions );
896 APPEND_TO_DRIVER_BLOCKLIST2( DRIVER_OS_ALL,
897 (nsAString&) GfxDriverInfo::GetDeviceVendor(VendorAMD), GfxDriverInfo::allDevices,
898 nsIGfxInfo::FEATURE_OPENGL_LAYERS, nsIGfxInfo::FEATURE_DISCOURAGED,
899 DRIVER_LESS_THAN, GfxDriverInfo::allDriverVersions );
900 APPEND_TO_DRIVER_BLOCKLIST2( DRIVER_OS_ALL,
901 (nsAString&) GfxDriverInfo::GetDeviceVendor(VendorAMD), GfxDriverInfo::allDevices,
902 nsIGfxInfo::FEATURE_WEBGL_OPENGL, nsIGfxInfo::FEATURE_DISCOURAGED,
903 DRIVER_LESS_THAN, GfxDriverInfo::allDriverVersions );
906 * Intel entries
909 /* The driver versions used here come from bug 594877. They might not
910 * be particularly relevant anymore.
912 #define IMPLEMENT_INTEL_DRIVER_BLOCKLIST(winVer, devFamily, driverVer) \
913 APPEND_TO_DRIVER_BLOCKLIST2( winVer, \
914 (nsAString&) GfxDriverInfo::GetDeviceVendor(VendorIntel), (GfxDeviceFamily*) GfxDriverInfo::GetDeviceFamily(devFamily), \
915 GfxDriverInfo::allFeatures, nsIGfxInfo::FEATURE_BLOCKED_DRIVER_VERSION, \
916 DRIVER_LESS_THAN, driverVer )
918 #define IMPLEMENT_INTEL_DRIVER_BLOCKLIST_D2D(winVer, devFamily, driverVer) \
919 APPEND_TO_DRIVER_BLOCKLIST2( winVer, \
920 (nsAString&) GfxDriverInfo::GetDeviceVendor(VendorIntel), (GfxDeviceFamily*) GfxDriverInfo::GetDeviceFamily(devFamily), \
921 nsIGfxInfo::FEATURE_DIRECT2D, nsIGfxInfo::FEATURE_BLOCKED_DRIVER_VERSION, \
922 DRIVER_LESS_THAN, driverVer )
924 IMPLEMENT_INTEL_DRIVER_BLOCKLIST_D2D(DRIVER_OS_WINDOWS_VISTA, IntelGMA500, V(7,14,10,1006));
925 IMPLEMENT_INTEL_DRIVER_BLOCKLIST_D2D(DRIVER_OS_WINDOWS_VISTA, IntelGMA900, GfxDriverInfo::allDriverVersions);
926 IMPLEMENT_INTEL_DRIVER_BLOCKLIST_D2D(DRIVER_OS_WINDOWS_VISTA, IntelGMA950, V(7,14,10,1504));
927 IMPLEMENT_INTEL_DRIVER_BLOCKLIST_D2D(DRIVER_OS_WINDOWS_VISTA, IntelGMA3150, V(7,14,10,2124));
928 IMPLEMENT_INTEL_DRIVER_BLOCKLIST_D2D(DRIVER_OS_WINDOWS_VISTA, IntelGMAX3000, V(7,15,10,1666));
929 IMPLEMENT_INTEL_DRIVER_BLOCKLIST_D2D(DRIVER_OS_WINDOWS_VISTA, IntelGMAX4500HD, V(8,15,10,2202));
931 IMPLEMENT_INTEL_DRIVER_BLOCKLIST_D2D(DRIVER_OS_WINDOWS_7, IntelGMA500, V(5,0,0,2026));
932 IMPLEMENT_INTEL_DRIVER_BLOCKLIST_D2D(DRIVER_OS_WINDOWS_7, IntelGMA900, GfxDriverInfo::allDriverVersions);
933 IMPLEMENT_INTEL_DRIVER_BLOCKLIST_D2D(DRIVER_OS_WINDOWS_7, IntelGMA950, V(8,15,10,1930));
934 IMPLEMENT_INTEL_DRIVER_BLOCKLIST_D2D(DRIVER_OS_WINDOWS_7, IntelGMA3150, V(8,14,10,2117));
935 IMPLEMENT_INTEL_DRIVER_BLOCKLIST_D2D(DRIVER_OS_WINDOWS_7, IntelGMAX3000, V(8,15,10,1930));
936 IMPLEMENT_INTEL_DRIVER_BLOCKLIST_D2D(DRIVER_OS_WINDOWS_7, IntelGMAX4500HD, V(8,15,10,2202));
938 IMPLEMENT_INTEL_DRIVER_BLOCKLIST(DRIVER_OS_WINDOWS_XP, IntelGMA500, V(3,0,20,3200));
939 IMPLEMENT_INTEL_DRIVER_BLOCKLIST(DRIVER_OS_WINDOWS_XP, IntelGMA900, V(6,14,10,4764));
940 IMPLEMENT_INTEL_DRIVER_BLOCKLIST(DRIVER_OS_WINDOWS_XP, IntelGMA950, V(6,14,10,4926));
941 IMPLEMENT_INTEL_DRIVER_BLOCKLIST(DRIVER_OS_WINDOWS_XP, IntelGMA3150, V(6,14,10,5134));
942 IMPLEMENT_INTEL_DRIVER_BLOCKLIST(DRIVER_OS_WINDOWS_XP, IntelGMAX3000, V(6,14,10,5218));
943 IMPLEMENT_INTEL_DRIVER_BLOCKLIST(DRIVER_OS_WINDOWS_XP, IntelGMAX4500HD, V(6,14,10,4969));
945 // StrechRect seems to suffer from precision issues which leads to artifacting
946 // during content drawing starting with at least version 6.14.10.5082
947 // and going until 6.14.10.5218. See bug 919454 and bug 949275 for more info.
948 APPEND_TO_DRIVER_BLOCKLIST_RANGE(DRIVER_OS_WINDOWS_XP,
949 const_cast<nsAString&>(GfxDriverInfo::GetDeviceVendor(VendorIntel)),
950 const_cast<GfxDeviceFamily*>(GfxDriverInfo::GetDeviceFamily(IntelGMAX4500HD)),
951 GfxDriverInfo::allFeatures, nsIGfxInfo::FEATURE_BLOCKED_DRIVER_VERSION,
952 DRIVER_BETWEEN_EXCLUSIVE, V(6,14,10,5076), V(6,14,10,5218), "6.14.10.5218");
954 IMPLEMENT_INTEL_DRIVER_BLOCKLIST(DRIVER_OS_WINDOWS_VISTA, IntelGMA500, V(3,0,20,3200));
955 IMPLEMENT_INTEL_DRIVER_BLOCKLIST(DRIVER_OS_WINDOWS_VISTA, IntelGMA900, GfxDriverInfo::allDriverVersions);
956 IMPLEMENT_INTEL_DRIVER_BLOCKLIST(DRIVER_OS_WINDOWS_VISTA, IntelGMA950, V(7,14,10,1504));
957 IMPLEMENT_INTEL_DRIVER_BLOCKLIST(DRIVER_OS_WINDOWS_VISTA, IntelGMA3150, V(7,14,10,1910));
958 IMPLEMENT_INTEL_DRIVER_BLOCKLIST(DRIVER_OS_WINDOWS_VISTA, IntelGMAX3000, V(7,15,10,1666));
959 IMPLEMENT_INTEL_DRIVER_BLOCKLIST(DRIVER_OS_WINDOWS_VISTA, IntelGMAX4500HD, V(7,15,10,1666));
961 IMPLEMENT_INTEL_DRIVER_BLOCKLIST(DRIVER_OS_WINDOWS_7, IntelGMA500, V(5,0,0,2026));
962 IMPLEMENT_INTEL_DRIVER_BLOCKLIST(DRIVER_OS_WINDOWS_7, IntelGMA900, GfxDriverInfo::allDriverVersions);
963 IMPLEMENT_INTEL_DRIVER_BLOCKLIST(DRIVER_OS_WINDOWS_7, IntelGMA950, V(8,15,10,1930));
964 IMPLEMENT_INTEL_DRIVER_BLOCKLIST(DRIVER_OS_WINDOWS_7, IntelGMA3150, V(8,14,10,1972));
965 IMPLEMENT_INTEL_DRIVER_BLOCKLIST(DRIVER_OS_WINDOWS_7, IntelGMAX3000, V(7,15,10,1666));
966 IMPLEMENT_INTEL_DRIVER_BLOCKLIST(DRIVER_OS_WINDOWS_7, IntelGMAX4500HD, V(7,15,10,1666));
968 /* OpenGL on any Intel hardware is discouraged */
969 APPEND_TO_DRIVER_BLOCKLIST2( DRIVER_OS_ALL,
970 (nsAString&) GfxDriverInfo::GetDeviceVendor(VendorIntel), GfxDriverInfo::allDevices,
971 nsIGfxInfo::FEATURE_OPENGL_LAYERS, nsIGfxInfo::FEATURE_DISCOURAGED,
972 DRIVER_LESS_THAN, GfxDriverInfo::allDriverVersions );
973 APPEND_TO_DRIVER_BLOCKLIST2( DRIVER_OS_ALL,
974 (nsAString&) GfxDriverInfo::GetDeviceVendor(VendorIntel), GfxDriverInfo::allDevices,
975 nsIGfxInfo::FEATURE_WEBGL_OPENGL, nsIGfxInfo::FEATURE_DISCOURAGED,
976 DRIVER_LESS_THAN, GfxDriverInfo::allDriverVersions );
979 * Disable acceleration on Intel HD 3000 for graphics drivers <= 8.15.10.2321.
980 * See bug 1018278 and bug 1060736.
982 APPEND_TO_DRIVER_BLOCKLIST( DRIVER_OS_ALL,
983 (nsAString&) GfxDriverInfo::GetDeviceVendor(VendorIntel), (GfxDeviceFamily*) GfxDriverInfo::GetDeviceFamily(IntelHD3000),
984 GfxDriverInfo::allFeatures, nsIGfxInfo::FEATURE_BLOCKED_DRIVER_VERSION,
985 DRIVER_LESS_THAN_OR_EQUAL, V(8,15,10,2321), "8.15.10.2342" );
987 /* Disable D2D on Win7 on Intel HD Graphics on driver <= 8.15.10.2302
988 * See bug 806786
990 APPEND_TO_DRIVER_BLOCKLIST2( DRIVER_OS_WINDOWS_7,
991 (nsAString&) GfxDriverInfo::GetDeviceVendor(VendorIntel), (GfxDeviceFamily*) GfxDriverInfo::GetDeviceFamily(IntelMobileHDGraphics),
992 nsIGfxInfo::FEATURE_DIRECT2D, nsIGfxInfo::FEATURE_BLOCKED_DRIVER_VERSION,
993 DRIVER_LESS_THAN_OR_EQUAL, V(8,15,10,2302) );
995 /* Disable D2D on Win8 on Intel HD Graphics on driver <= 8.15.10.2302
996 * See bug 804144 and 863683
998 APPEND_TO_DRIVER_BLOCKLIST2( DRIVER_OS_WINDOWS_8,
999 (nsAString&) GfxDriverInfo::GetDeviceVendor(VendorIntel), (GfxDeviceFamily*) GfxDriverInfo::GetDeviceFamily(IntelMobileHDGraphics),
1000 nsIGfxInfo::FEATURE_DIRECT2D, nsIGfxInfo::FEATURE_BLOCKED_DRIVER_VERSION,
1001 DRIVER_LESS_THAN_OR_EQUAL, V(8,15,10,2302) );
1003 /* Disable D2D on AMD Catalyst 14.4 until 14.6
1004 * See bug 984488
1006 APPEND_TO_DRIVER_BLOCKLIST_RANGE( DRIVER_OS_ALL,
1007 (nsAString&) GfxDriverInfo::GetDeviceVendor(VendorATI), GfxDriverInfo::allDevices,
1008 nsIGfxInfo::FEATURE_DIRECT2D, nsIGfxInfo::FEATURE_BLOCKED_DRIVER_VERSION,
1009 DRIVER_BETWEEN_INCLUSIVE_START, V(14,1,0,0), V(14,2,0,0), "ATI Catalyst 14.6+");
1010 APPEND_TO_DRIVER_BLOCKLIST_RANGE( DRIVER_OS_ALL,
1011 (nsAString&) GfxDriverInfo::GetDeviceVendor(VendorAMD), GfxDriverInfo::allDevices,
1012 nsIGfxInfo::FEATURE_DIRECT2D, nsIGfxInfo::FEATURE_BLOCKED_DRIVER_VERSION,
1013 DRIVER_BETWEEN_INCLUSIVE_START, V(14,1,0,0), V(14,2,0,0), "ATI Catalyst 14.6+");
1015 /* Disable D3D9 layers on NVIDIA 6100/6150/6200 series due to glitches
1016 * whilst scrolling. See bugs: 612007, 644787 & 645872.
1018 APPEND_TO_DRIVER_BLOCKLIST2( DRIVER_OS_ALL,
1019 (nsAString&) GfxDriverInfo::GetDeviceVendor(VendorNVIDIA), (GfxDeviceFamily*) GfxDriverInfo::GetDeviceFamily(NvidiaBlockD3D9Layers),
1020 nsIGfxInfo::FEATURE_DIRECT3D_9_LAYERS, nsIGfxInfo::FEATURE_BLOCKED_DEVICE,
1021 DRIVER_LESS_THAN, GfxDriverInfo::allDriverVersions );
1023 /* Microsoft RemoteFX; blocked less than 6.2.0.0 */
1024 APPEND_TO_DRIVER_BLOCKLIST( DRIVER_OS_ALL,
1025 (nsAString&) GfxDriverInfo::GetDeviceVendor(VendorMicrosoft), GfxDriverInfo::allDevices,
1026 GfxDriverInfo::allFeatures, nsIGfxInfo::FEATURE_BLOCKED_DRIVER_VERSION,
1027 DRIVER_LESS_THAN, V(6,2,0,0), "< 6.2.0.0" );
1029 /* Bug 1008759: Optimus (NVidia) crash. Disable D2D on NV 310M. */
1030 APPEND_TO_DRIVER_BLOCKLIST2(DRIVER_OS_ALL,
1031 (nsAString&)GfxDriverInfo::GetDeviceVendor(VendorNVIDIA), (GfxDeviceFamily*)GfxDriverInfo::GetDeviceFamily(Nvidia310M),
1032 nsIGfxInfo::FEATURE_DIRECT2D, nsIGfxInfo::FEATURE_BLOCKED_DEVICE,
1033 DRIVER_LESS_THAN, GfxDriverInfo::allDriverVersions);
1035 return *mDriverInfo;
1038 nsresult
1039 GfxInfo::GetFeatureStatusImpl(int32_t aFeature,
1040 int32_t *aStatus,
1041 nsAString & aSuggestedDriverVersion,
1042 const nsTArray<GfxDriverInfo>& aDriverInfo,
1043 OperatingSystem* aOS /* = nullptr */)
1045 NS_ENSURE_ARG_POINTER(aStatus);
1046 aSuggestedDriverVersion.SetIsVoid(true);
1047 OperatingSystem os = WindowsVersionToOperatingSystem(mWindowsVersion);
1048 *aStatus = nsIGfxInfo::FEATURE_STATUS_UNKNOWN;
1049 if (aOS)
1050 *aOS = os;
1052 // Don't evaluate special cases if we're checking the downloaded blocklist.
1053 if (!aDriverInfo.Length()) {
1054 nsAutoString adapterVendorID;
1055 nsAutoString adapterDeviceID;
1056 nsAutoString adapterDriverVersionString;
1057 if (NS_FAILED(GetAdapterVendorID(adapterVendorID)) ||
1058 NS_FAILED(GetAdapterDeviceID(adapterDeviceID)) ||
1059 NS_FAILED(GetAdapterDriverVersion(adapterDriverVersionString)))
1061 return NS_ERROR_FAILURE;
1064 if (!adapterVendorID.Equals(GfxDriverInfo::GetDeviceVendor(VendorIntel), nsCaseInsensitiveStringComparator()) &&
1065 !adapterVendorID.Equals(GfxDriverInfo::GetDeviceVendor(VendorNVIDIA), nsCaseInsensitiveStringComparator()) &&
1066 !adapterVendorID.Equals(GfxDriverInfo::GetDeviceVendor(VendorAMD), nsCaseInsensitiveStringComparator()) &&
1067 !adapterVendorID.Equals(GfxDriverInfo::GetDeviceVendor(VendorATI), nsCaseInsensitiveStringComparator()) &&
1068 !adapterVendorID.Equals(GfxDriverInfo::GetDeviceVendor(VendorMicrosoft), nsCaseInsensitiveStringComparator()) &&
1069 // FIXME - these special hex values are currently used in xpcshell tests introduced by
1070 // bug 625160 patch 8/8. Maybe these tests need to be adjusted now that we're only whitelisting
1071 // intel/ati/nvidia.
1072 !adapterVendorID.LowerCaseEqualsLiteral("0xabcd") &&
1073 !adapterVendorID.LowerCaseEqualsLiteral("0xdcba") &&
1074 !adapterVendorID.LowerCaseEqualsLiteral("0xabab") &&
1075 !adapterVendorID.LowerCaseEqualsLiteral("0xdcdc"))
1077 *aStatus = FEATURE_BLOCKED_DEVICE;
1078 return NS_OK;
1081 uint64_t driverVersion;
1082 if (!ParseDriverVersion(adapterDriverVersionString, &driverVersion)) {
1083 return NS_ERROR_FAILURE;
1086 // special-case the WinXP test slaves: they have out-of-date drivers, but we still want to
1087 // whitelist them, actually we do know that this combination of device and driver version
1088 // works well.
1089 if (mWindowsVersion == kWindowsXP &&
1090 adapterVendorID.Equals(GfxDriverInfo::GetDeviceVendor(VendorNVIDIA), nsCaseInsensitiveStringComparator()) &&
1091 adapterDeviceID.LowerCaseEqualsLiteral("0x0861") && // GeForce 9400
1092 driverVersion == V(6,14,11,7756))
1094 *aStatus = FEATURE_STATUS_OK;
1095 return NS_OK;
1098 // Windows Server 2003 should be just like Windows XP for present purpose, but still has a different version number.
1099 // OTOH Windows Server 2008 R1 and R2 already have the same version numbers as Vista and Seven respectively
1100 if (os == DRIVER_OS_WINDOWS_SERVER_2003)
1101 os = DRIVER_OS_WINDOWS_XP;
1103 if (mHasDriverVersionMismatch) {
1104 if (aFeature == nsIGfxInfo::FEATURE_DIRECT3D_10_LAYERS ||
1105 aFeature == nsIGfxInfo::FEATURE_DIRECT3D_10_1_LAYERS ||
1106 aFeature == nsIGfxInfo::FEATURE_DIRECT2D ||
1107 aFeature == nsIGfxInfo::FEATURE_DIRECT3D_11_LAYERS)
1109 *aStatus = nsIGfxInfo::FEATURE_BLOCKED_DRIVER_VERSION;
1110 return NS_OK;
1115 return GfxInfoBase::GetFeatureStatusImpl(aFeature, aStatus, aSuggestedDriverVersion, aDriverInfo, &os);
1118 #ifdef DEBUG
1120 // Implement nsIGfxInfoDebug
1122 /* void spoofVendorID (in DOMString aVendorID); */
1123 NS_IMETHODIMP GfxInfo::SpoofVendorID(const nsAString & aVendorID)
1125 mAdapterVendorID = aVendorID;
1126 return NS_OK;
1129 /* void spoofDeviceID (in unsigned long aDeviceID); */
1130 NS_IMETHODIMP GfxInfo::SpoofDeviceID(const nsAString & aDeviceID)
1132 mAdapterDeviceID = aDeviceID;
1133 return NS_OK;
1136 /* void spoofDriverVersion (in DOMString aDriverVersion); */
1137 NS_IMETHODIMP GfxInfo::SpoofDriverVersion(const nsAString & aDriverVersion)
1139 mDriverVersion = aDriverVersion;
1140 return NS_OK;
1143 /* void spoofOSVersion (in unsigned long aVersion); */
1144 NS_IMETHODIMP GfxInfo::SpoofOSVersion(uint32_t aVersion)
1146 mWindowsVersion = aVersion;
1147 return NS_OK;
1150 #endif