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"
9 #include <devguid.h> // for GUID_DEVCLASS_BATTERY
10 #include <setupapi.h> // for SetupDi*
11 #include <winioctl.h> // for IOCTL_*
12 #include <batclass.h> // for BATTERY_*
13 #include "gfxConfig.h"
14 #include "gfxWindowsPlatform.h"
16 #include "nsUnicharUtils.h"
19 #include "GfxDriverInfo.h"
20 #include "mozilla/Components.h"
21 #include "mozilla/Preferences.h"
22 #include "mozilla/gfx/DeviceManagerDx.h"
23 #include "mozilla/gfx/Logging.h"
24 #include "mozilla/SSE.h"
25 #include "nsExceptionHandler.h"
26 #include "nsPrintfCString.h"
30 #define NS_CRASHREPORTER_CONTRACTID "@mozilla.org/toolkit/crash-reporter;1"
32 using namespace mozilla
;
33 using namespace mozilla::gfx
;
34 using namespace mozilla::widget
;
37 NS_IMPL_ISUPPORTS_INHERITED(GfxInfo
, GfxInfoBase
, nsIGfxInfoDebug
)
42 mWindowsBuildNumber(0),
47 /* GetD2DEnabled and GetDwriteEnabled shouldn't be called until after
48 * gfxPlatform initialization has occurred because they depend on it for
49 * information. (See bug 591561) */
50 nsresult
GfxInfo::GetD2DEnabled(bool* aEnabled
) {
51 // Telemetry queries this during XPCOM initialization, and there's no
52 // gfxPlatform by then. Just bail out if gfxPlatform isn't initialized.
53 if (!gfxPlatform::Initialized()) {
58 // We check gfxConfig rather than the actual render mode, since the UI
59 // process does not use Direct2D if the GPU process is enabled. However,
60 // content processes can still use Direct2D.
61 *aEnabled
= gfx::gfxConfig::IsEnabled(gfx::Feature::DIRECT2D
);
65 nsresult
GfxInfo::GetDWriteEnabled(bool* aEnabled
) {
66 *aEnabled
= gfxWindowsPlatform::GetPlatform()->DWriteEnabled();
71 GfxInfo::GetDWriteVersion(nsAString
& aDwriteVersion
) {
72 gfxWindowsPlatform::GetDLLVersion(L
"dwrite.dll", aDwriteVersion
);
77 GfxInfo::GetHasBattery(bool* aHasBattery
) {
78 *aHasBattery
= mHasBattery
;
82 int32_t GfxInfo::GetMaxRefreshRate(bool* aMixed
) {
83 int32_t maxRefreshRate
= -1;
88 for (auto displayInfo
: mDisplayInfo
) {
89 int32_t refreshRate
= int32_t(displayInfo
.mRefreshRate
);
90 if (aMixed
&& maxRefreshRate
> 0 && maxRefreshRate
!= refreshRate
) {
93 maxRefreshRate
= std::max(maxRefreshRate
, refreshRate
);
95 return maxRefreshRate
;
99 GfxInfo::GetEmbeddedInFirefoxReality(bool* aEmbeddedInFirefoxReality
) {
100 *aEmbeddedInFirefoxReality
= gfxVars::FxREmbedded();
104 #define PIXEL_STRUCT_RGB 1
105 #define PIXEL_STRUCT_BGR 2
108 GfxInfo::GetCleartypeParameters(nsAString
& aCleartypeParams
) {
109 nsTArray
<ClearTypeParameterInfo
> clearTypeParams
;
111 gfxWindowsPlatform::GetPlatform()->GetCleartypeParams(clearTypeParams
);
112 uint32_t d
, numDisplays
= clearTypeParams
.Length();
113 bool displayNames
= (numDisplays
> 1);
114 bool foundData
= false;
117 for (d
= 0; d
< numDisplays
; d
++) {
118 ClearTypeParameterInfo
& params
= clearTypeParams
[d
];
121 outStr
.AppendPrintf("%S [ ", params
.displayName
.get());
124 if (params
.gamma
>= 0) {
126 outStr
.AppendPrintf("Gamma: %.4g ", params
.gamma
/ 1000.0);
129 if (params
.pixelStructure
>= 0) {
131 if (params
.pixelStructure
== PIXEL_STRUCT_RGB
||
132 params
.pixelStructure
== PIXEL_STRUCT_BGR
) {
134 "Pixel Structure: %S ",
135 (params
.pixelStructure
== PIXEL_STRUCT_RGB
? u
"RGB" : u
"BGR"));
137 outStr
.AppendPrintf("Pixel Structure: %d ", params
.pixelStructure
);
141 if (params
.clearTypeLevel
>= 0) {
143 outStr
.AppendPrintf("ClearType Level: %d ", params
.clearTypeLevel
);
146 if (params
.enhancedContrast
>= 0) {
148 outStr
.AppendPrintf("Enhanced Contrast: %d ", params
.enhancedContrast
);
152 outStr
.Append(u
"] ");
157 aCleartypeParams
.Assign(outStr
);
160 return NS_ERROR_FAILURE
;
164 GfxInfo::GetWindowProtocol(nsAString
& aWindowProtocol
) {
165 return NS_ERROR_NOT_IMPLEMENTED
;
169 GfxInfo::GetDesktopEnvironment(nsAString
& aDesktopEnvironment
) {
170 return NS_ERROR_NOT_IMPLEMENTED
;
174 GfxInfo::GetTestType(nsAString
& aTestType
) { return NS_ERROR_NOT_IMPLEMENTED
; }
176 static nsresult
GetKeyValue(const WCHAR
* keyLocation
, const WCHAR
* keyName
,
177 uint32_t& destValue
, int type
) {
178 MOZ_ASSERT(type
== REG_DWORD
|| type
== REG_QWORD
);
184 nsresult retval
= NS_OK
;
187 RegOpenKeyExW(HKEY_LOCAL_MACHINE
, keyLocation
, 0, KEY_QUERY_VALUE
, &key
);
188 if (result
!= ERROR_SUCCESS
) {
189 return NS_ERROR_FAILURE
;
194 // We only use this for vram size
195 dwcbData
= sizeof(dValue
);
196 result
= RegQueryValueExW(key
, keyName
, nullptr, &resultType
,
197 (LPBYTE
)&dValue
, &dwcbData
);
198 if (result
== ERROR_SUCCESS
&& resultType
== REG_DWORD
) {
199 destValue
= (uint32_t)(dValue
/ 1024 / 1024);
201 retval
= NS_ERROR_FAILURE
;
206 // We only use this for vram size
208 dwcbData
= sizeof(qValue
);
209 result
= RegQueryValueExW(key
, keyName
, nullptr, &resultType
,
210 (LPBYTE
)&qValue
, &dwcbData
);
211 if (result
== ERROR_SUCCESS
&& resultType
== REG_QWORD
) {
212 destValue
= (uint32_t)(qValue
/ 1024 / 1024);
214 retval
= NS_ERROR_FAILURE
;
224 static nsresult
GetKeyValue(const WCHAR
* keyLocation
, const WCHAR
* keyName
,
225 nsAString
& destString
, int type
) {
226 MOZ_ASSERT(type
== REG_MULTI_SZ
);
232 nsresult retval
= NS_OK
;
235 RegOpenKeyExW(HKEY_LOCAL_MACHINE
, keyLocation
, 0, KEY_QUERY_VALUE
, &key
);
236 if (result
!= ERROR_SUCCESS
) {
237 return NS_ERROR_FAILURE
;
240 // A chain of null-separated strings; we convert the nulls to spaces
241 WCHAR wCharValue
[1024];
242 dwcbData
= sizeof(wCharValue
);
244 result
= RegQueryValueExW(key
, keyName
, nullptr, &resultType
,
245 (LPBYTE
)wCharValue
, &dwcbData
);
246 if (result
== ERROR_SUCCESS
&& resultType
== REG_MULTI_SZ
) {
247 // This bit here could probably be cleaner.
248 bool isValid
= false;
250 DWORD strLen
= dwcbData
/ sizeof(wCharValue
[0]);
251 for (DWORD i
= 0; i
< strLen
; i
++) {
252 if (wCharValue
[i
] == '\0') {
253 if (i
< strLen
- 1 && wCharValue
[i
+ 1] == '\0') {
262 // ensure wCharValue is null terminated
263 wCharValue
[strLen
- 1] = '\0';
265 if (isValid
) destString
= wCharValue
;
268 retval
= NS_ERROR_FAILURE
;
276 static nsresult
GetKeyValues(const WCHAR
* keyLocation
, const WCHAR
* keyName
,
277 nsTArray
<nsString
>& destStrings
) {
278 // First ask for the size of the value
280 LONG rv
= RegGetValueW(HKEY_LOCAL_MACHINE
, keyLocation
, keyName
,
281 RRF_RT_REG_MULTI_SZ
, nullptr, nullptr, &size
);
282 if (rv
!= ERROR_SUCCESS
) {
283 return NS_ERROR_FAILURE
;
286 // Create a buffer with the proper size and retrieve the value
287 WCHAR
* wCharValue
= new WCHAR
[size
/ sizeof(WCHAR
)];
288 rv
= RegGetValueW(HKEY_LOCAL_MACHINE
, keyLocation
, keyName
,
289 RRF_RT_REG_MULTI_SZ
, nullptr, (LPBYTE
)wCharValue
, &size
);
290 if (rv
!= ERROR_SUCCESS
) {
292 return NS_ERROR_FAILURE
;
295 // The value is a sequence of null-terminated strings, usually terminated by
296 // an empty string (\0). RegGetValue ensures that the value is properly
297 // terminated with a null character.
299 DWORD strLen
= size
/ sizeof(WCHAR
);
301 nsString
value(wCharValue
+ i
);
302 if (!value
.IsEmpty()) {
303 destStrings
.AppendElement(value
);
305 i
+= value
.Length() + 1;
312 // The device ID is a string like PCI\VEN_15AD&DEV_0405&SUBSYS_040515AD
313 // this function is used to extract the id's out of it
314 uint32_t ParseIDFromDeviceID(const nsAString
& key
, const char* prefix
,
316 nsAutoString
id(key
);
318 int32_t start
= id
.Find(prefix
);
320 id
.Cut(0, start
+ strlen(prefix
));
323 if (id
.Equals(L
"QCOM", nsCaseInsensitiveStringComparator
)) {
324 // String format assumptions are broken, so use a Qualcomm PCI Vendor ID
325 // for now. See also GfxDriverInfo::GetDeviceVendor.
329 return id
.ToInteger(&err
, 16);
332 // OS version in 16.16 major/minor form
333 // based on http://msdn.microsoft.com/en-us/library/ms724834(VS.85).aspx
338 kWindows8_1
= 0x60003,
342 static bool HasBattery() {
343 // Helper classes to manage lifetimes of Windows structs.
344 class MOZ_STACK_CLASS HDevInfoHolder final
{
346 explicit HDevInfoHolder(HDEVINFO aHandle
) : mHandle(aHandle
) {}
348 ~HDevInfoHolder() { ::SetupDiDestroyDeviceInfoList(mHandle
); }
354 class MOZ_STACK_CLASS HandleHolder final
{
356 explicit HandleHolder(HANDLE aHandle
) : mHandle(aHandle
) {}
358 ~HandleHolder() { ::CloseHandle(mHandle
); }
365 ::SetupDiGetClassDevs(&GUID_DEVCLASS_BATTERY
, nullptr, nullptr,
366 DIGCF_PRESENT
| DIGCF_DEVICEINTERFACE
);
367 if (hdev
== INVALID_HANDLE_VALUE
) {
371 HDevInfoHolder
hdevHolder(hdev
);
374 SP_DEVICE_INTERFACE_DATA did
= {0};
375 did
.cbSize
= sizeof(did
);
377 while (::SetupDiEnumDeviceInterfaces(hdev
, nullptr, &GUID_DEVCLASS_BATTERY
, i
,
379 DWORD bufferSize
= 0;
380 ::SetupDiGetDeviceInterfaceDetail(hdev
, &did
, nullptr, 0, &bufferSize
,
382 if (::GetLastError() != ERROR_INSUFFICIENT_BUFFER
) {
386 UniquePtr
<uint8_t[]> buffer(new (std::nothrow
) uint8_t[bufferSize
]);
391 PSP_DEVICE_INTERFACE_DETAIL_DATA pdidd
=
392 reinterpret_cast<PSP_DEVICE_INTERFACE_DETAIL_DATA
>(buffer
.get());
393 pdidd
->cbSize
= sizeof(*pdidd
);
394 if (!::SetupDiGetDeviceInterfaceDetail(hdev
, &did
, pdidd
, bufferSize
,
395 &bufferSize
, nullptr)) {
399 HANDLE hbat
= ::CreateFile(pdidd
->DevicePath
, GENERIC_READ
| GENERIC_WRITE
,
400 FILE_SHARE_READ
| FILE_SHARE_WRITE
, nullptr,
401 OPEN_EXISTING
, FILE_ATTRIBUTE_NORMAL
, nullptr);
402 if (hbat
== INVALID_HANDLE_VALUE
) {
406 HandleHolder
hbatHolder(hbat
);
408 BATTERY_QUERY_INFORMATION bqi
= {0};
412 // We need the tag to query the information below.
413 if (!::DeviceIoControl(hbat
, IOCTL_BATTERY_QUERY_TAG
, &dwWait
,
414 sizeof(dwWait
), &bqi
.BatteryTag
,
415 sizeof(bqi
.BatteryTag
), &dwOut
, nullptr) ||
420 BATTERY_INFORMATION bi
= {0};
421 bqi
.InformationLevel
= BatteryInformation
;
423 if (!::DeviceIoControl(hbat
, IOCTL_BATTERY_QUERY_INFORMATION
, &bqi
,
424 sizeof(bqi
), &bi
, sizeof(bi
), &dwOut
, nullptr)) {
428 // If a battery intended for general use (i.e. system use) is not a UPS
429 // (i.e. short term), then we know for certain we have a battery.
430 if ((bi
.Capabilities
& BATTERY_SYSTEM_BATTERY
) &&
431 !(bi
.Capabilities
& BATTERY_IS_SHORT_TERM
)) {
435 // Otherwise we check the next battery.
439 // If we fail to enumerate because there are no more batteries to check, then
440 // we can safely say there are indeed no system batteries.
441 return ::GetLastError() != ERROR_NO_MORE_ITEMS
;
444 /* Other interesting places for info:
445 * IDXGIAdapter::GetDesc()
446 * IDirectDraw7::GetAvailableVidMem()
447 * e->GetAvailableTextureMem()
450 #define DEVICE_KEY_PREFIX L"\\Registry\\Machine\\"
451 nsresult
GfxInfo::Init() {
452 nsresult rv
= GfxInfoBase::Init();
453 mHasBattery
= HasBattery();
455 DISPLAY_DEVICEW displayDevice
;
456 displayDevice
.cb
= sizeof(displayDevice
);
459 const char* spoofedWindowsVersion
=
460 PR_GetEnv("MOZ_GFX_SPOOF_WINDOWS_VERSION");
461 if (spoofedWindowsVersion
) {
462 PR_sscanf(spoofedWindowsVersion
, "%x,%u", &mWindowsVersion
,
463 &mWindowsBuildNumber
);
466 vinfo
.dwOSVersionInfoSize
= sizeof(vinfo
);
468 # pragma warning(push)
469 # pragma warning(disable : 4996)
471 if (!GetVersionEx(&vinfo
)) {
473 # pragma warning(pop)
475 mWindowsVersion
= kWindowsUnknown
;
478 int32_t(vinfo
.dwMajorVersion
<< 16) + vinfo
.dwMinorVersion
;
479 mWindowsBuildNumber
= vinfo
.dwBuildNumber
;
483 mDeviceKeyDebug
= u
"PrimarySearch"_ns
;
485 while (EnumDisplayDevicesW(nullptr, deviceIndex
, &displayDevice
, 0)) {
486 if (displayDevice
.StateFlags
& DISPLAY_DEVICE_PRIMARY_DEVICE
) {
487 mDeviceKeyDebug
= u
"NullSearch"_ns
;
493 // make sure the string is nullptr terminated
494 if (wcsnlen(displayDevice
.DeviceKey
, ArrayLength(displayDevice
.DeviceKey
)) ==
495 ArrayLength(displayDevice
.DeviceKey
)) {
496 // we did not find a nullptr
500 mDeviceKeyDebug
= displayDevice
.DeviceKey
;
502 /* DeviceKey is "reserved" according to MSDN so we'll be careful with it */
503 /* check that DeviceKey begins with DEVICE_KEY_PREFIX */
504 /* some systems have a DeviceKey starting with \REGISTRY\Machine\ so we need
505 * to compare case insenstively */
506 /* If the device key is empty, we are most likely in a remote desktop
507 * environment. In this case we set the devicekey to an empty string so
508 * it can be handled later.
510 if (displayDevice
.DeviceKey
[0] != '\0') {
511 if (_wcsnicmp(displayDevice
.DeviceKey
, DEVICE_KEY_PREFIX
,
512 ArrayLength(DEVICE_KEY_PREFIX
) - 1) != 0) {
516 // chop off DEVICE_KEY_PREFIX
518 displayDevice
.DeviceKey
+ ArrayLength(DEVICE_KEY_PREFIX
) - 1;
520 mDeviceKey
[0].Truncate();
523 mDeviceID
[0] = displayDevice
.DeviceID
;
524 mDeviceString
[0] = displayDevice
.DeviceString
;
526 // On Windows 8 and Server 2012 hosts, we want to not block RDP
527 // sessions from attempting hardware acceleration. RemoteFX
528 // provides features and functionaltiy that can give a good D3D10 +
529 // D2D + DirectWrite experience emulated via a software GPU.
531 // Unfortunately, the Device ID is nullptr, and we can't enumerate
532 // it using the setup infrastructure (SetupDiGetClassDevsW below
533 // will return INVALID_HANDLE_VALUE).
534 UINT flags
= DIGCF_PRESENT
| DIGCF_PROFILE
| DIGCF_ALLCLASSES
;
535 if (mWindowsVersion
>= kWindows8
&& mDeviceID
[0].Length() == 0 &&
536 mDeviceString
[0].EqualsLiteral("RDPUDD Chained DD")) {
538 UINT len
= GetSystemDirectory(sysdir
, sizeof(sysdir
));
539 if (len
< sizeof(sysdir
)) {
540 nsString
rdpudd(sysdir
);
541 rdpudd
.AppendLiteral("\\rdpudd.dll");
542 gfxWindowsPlatform::GetDLLVersion(rdpudd
.BeginReading(),
544 mDriverDate
[0].AssignLiteral("01-01-1970");
546 // 0x1414 is Microsoft; 0xfefe is an invented (and unused) code
547 mDeviceID
[0].AssignLiteral("PCI\\VEN_1414&DEV_FEFE&SUBSYS_00000000");
548 flags
|= DIGCF_DEVICEINTERFACE
;
552 /* create a device information set composed of the current display device */
554 SetupDiGetClassDevsW(nullptr, mDeviceID
[0].get(), nullptr, flags
);
556 if (devinfo
!= INVALID_HANDLE_VALUE
) {
561 SP_DEVINFO_DATA devinfoData
;
562 DWORD memberIndex
= 0;
564 devinfoData
.cbSize
= sizeof(devinfoData
);
565 constexpr auto driverKeyPre
=
566 u
"System\\CurrentControlSet\\Control\\Class\\"_ns
;
567 /* enumerate device information elements in the device information set */
568 while (SetupDiEnumDeviceInfo(devinfo
, memberIndex
++, &devinfoData
)) {
569 /* get a string that identifies the device's driver key */
570 if (SetupDiGetDeviceRegistryPropertyW(devinfo
, &devinfoData
, SPDRP_DRIVER
,
571 nullptr, (PBYTE
)value
,
572 sizeof(value
), nullptr)) {
573 nsAutoString
driverKey(driverKeyPre
);
575 result
= RegOpenKeyExW(HKEY_LOCAL_MACHINE
, driverKey
.get(), 0,
576 KEY_QUERY_VALUE
, &key
);
577 if (result
== ERROR_SUCCESS
) {
578 /* we've found the driver we're looking for */
579 dwcbData
= sizeof(value
);
580 result
= RegQueryValueExW(key
, L
"DriverVersion", nullptr, nullptr,
581 (LPBYTE
)value
, &dwcbData
);
582 if (result
== ERROR_SUCCESS
) {
583 mDriverVersion
[0] = value
;
585 // If the entry wasn't found, assume the worst (0.0.0.0).
586 mDriverVersion
[0].AssignLiteral("0.0.0.0");
588 dwcbData
= sizeof(value
);
589 result
= RegQueryValueExW(key
, L
"DriverDate", nullptr, nullptr,
590 (LPBYTE
)value
, &dwcbData
);
591 if (result
== ERROR_SUCCESS
) {
592 mDriverDate
[0] = value
;
594 // Again, assume the worst
595 mDriverDate
[0].AssignLiteral("01-01-1970");
603 SetupDiDestroyDeviceInfoList(devinfo
);
606 // It is convenient to have these as integers
607 uint32_t adapterVendorID
[2] = {0, 0};
608 uint32_t adapterDeviceID
[2] = {0, 0};
609 uint32_t adapterSubsysID
[2] = {0, 0};
611 adapterVendorID
[0] = ParseIDFromDeviceID(mDeviceID
[0], "VEN_", 4);
612 adapterDeviceID
[0] = ParseIDFromDeviceID(mDeviceID
[0], "&DEV_", 4);
613 adapterSubsysID
[0] = ParseIDFromDeviceID(mDeviceID
[0], "&SUBSYS_", 8);
615 // Sometimes we don't get the valid device using this method. For now,
616 // allow zero vendor or device as valid, as long as the other value is
618 bool foundValidDevice
= (adapterVendorID
[0] != 0 || adapterDeviceID
[0] != 0);
620 // We now check for second display adapter. If we didn't find the valid
621 // device using the original approach, we will try the alternative.
623 // Device interface class for display adapters.
624 CLSID GUID_DISPLAY_DEVICE_ARRIVAL
;
625 HRESULT hresult
= CLSIDFromString(L
"{1CA05180-A699-450A-9A0C-DE4FBE3DDD89}",
626 &GUID_DISPLAY_DEVICE_ARRIVAL
);
627 if (hresult
== NOERROR
) {
629 SetupDiGetClassDevsW(&GUID_DISPLAY_DEVICE_ARRIVAL
, nullptr, nullptr,
630 DIGCF_PRESENT
| DIGCF_INTERFACEDEVICE
);
632 if (devinfo
!= INVALID_HANDLE_VALUE
) {
637 SP_DEVINFO_DATA devinfoData
;
638 DWORD memberIndex
= 0;
639 devinfoData
.cbSize
= sizeof(devinfoData
);
641 nsAutoString adapterDriver2
;
642 nsAutoString deviceID2
;
643 nsAutoString driverVersion2
;
644 nsAutoString driverDate2
;
646 constexpr auto driverKeyPre
=
647 u
"System\\CurrentControlSet\\Control\\Class\\"_ns
;
648 /* enumerate device information elements in the device information set */
649 while (SetupDiEnumDeviceInfo(devinfo
, memberIndex
++, &devinfoData
)) {
650 /* get a string that identifies the device's driver key */
651 if (SetupDiGetDeviceRegistryPropertyW(
652 devinfo
, &devinfoData
, SPDRP_DRIVER
, nullptr, (PBYTE
)value
,
653 sizeof(value
), nullptr)) {
654 nsAutoString
driverKey2(driverKeyPre
);
656 result
= RegOpenKeyExW(HKEY_LOCAL_MACHINE
, driverKey2
.get(), 0,
657 KEY_QUERY_VALUE
, &key
);
658 if (result
== ERROR_SUCCESS
) {
659 dwcbData
= sizeof(value
);
660 result
= RegQueryValueExW(key
, L
"MatchingDeviceId", nullptr,
661 nullptr, (LPBYTE
)value
, &dwcbData
);
662 if (result
!= ERROR_SUCCESS
) {
666 adapterVendorID
[1] = ParseIDFromDeviceID(deviceID2
, "VEN_", 4);
667 adapterDeviceID
[1] = ParseIDFromDeviceID(deviceID2
, "&DEV_", 4);
668 // Skip the devices we already considered, as well as any
670 if ((adapterVendorID
[0] == adapterVendorID
[1] &&
671 adapterDeviceID
[0] == adapterDeviceID
[1]) ||
672 (adapterVendorID
[1] == 0 && adapterDeviceID
[1] == 0)) {
677 // If this device is missing driver information, it is unlikely to
678 // be a real display adapter.
679 if (NS_FAILED(GetKeyValue(driverKey2
.get(),
680 L
"InstalledDisplayDrivers",
681 adapterDriver2
, REG_MULTI_SZ
))) {
685 dwcbData
= sizeof(value
);
686 result
= RegQueryValueExW(key
, L
"DriverVersion", nullptr, nullptr,
687 (LPBYTE
)value
, &dwcbData
);
688 if (result
!= ERROR_SUCCESS
) {
692 driverVersion2
= value
;
693 dwcbData
= sizeof(value
);
694 result
= RegQueryValueExW(key
, L
"DriverDate", nullptr, nullptr,
695 (LPBYTE
)value
, &dwcbData
);
696 if (result
!= ERROR_SUCCESS
) {
701 dwcbData
= sizeof(value
);
702 result
= RegQueryValueExW(key
, L
"Device Description", nullptr,
703 nullptr, (LPBYTE
)value
, &dwcbData
);
704 if (result
!= ERROR_SUCCESS
) {
705 dwcbData
= sizeof(value
);
706 result
= RegQueryValueExW(key
, L
"DriverDesc", nullptr, nullptr,
707 (LPBYTE
)value
, &dwcbData
);
710 if (result
== ERROR_SUCCESS
) {
711 // If we didn't find a valid device with the original method
712 // take this one, and continue looking for the second GPU.
713 if (!foundValidDevice
) {
714 foundValidDevice
= true;
715 adapterVendorID
[0] = adapterVendorID
[1];
716 adapterDeviceID
[0] = adapterDeviceID
[1];
717 mDeviceString
[0] = value
;
718 mDeviceID
[0] = deviceID2
;
719 mDeviceKey
[0] = driverKey2
;
720 mDriverVersion
[0] = driverVersion2
;
721 mDriverDate
[0] = driverDate2
;
723 ParseIDFromDeviceID(mDeviceID
[0], "&SUBSYS_", 8);
728 mDeviceString
[1] = value
;
729 mDeviceID
[1] = deviceID2
;
730 mDeviceKey
[1] = driverKey2
;
731 mDriverVersion
[1] = driverVersion2
;
732 mDriverDate
[1] = driverDate2
;
734 ParseIDFromDeviceID(mDeviceID
[1], "&SUBSYS_", 8);
735 mAdapterVendorID
[1].AppendPrintf("0x%04x", adapterVendorID
[1]);
736 mAdapterDeviceID
[1].AppendPrintf("0x%04x", adapterDeviceID
[1]);
737 mAdapterSubsysID
[1].AppendPrintf("%08x", adapterSubsysID
[1]);
744 SetupDiDestroyDeviceInfoList(devinfo
);
748 mAdapterVendorID
[0].AppendPrintf("0x%04x", adapterVendorID
[0]);
749 mAdapterDeviceID
[0].AppendPrintf("0x%04x", adapterDeviceID
[0]);
750 mAdapterSubsysID
[0].AppendPrintf("%08x", adapterSubsysID
[0]);
752 // Sometimes, the enumeration is not quite right and the two adapters
753 // end up being swapped. Actually enumerate the adapters that come
754 // back from the DXGI factory to check, and tag the second as active
757 nsModuleHandle
dxgiModule(LoadLibrarySystem32(L
"dxgi.dll"));
758 decltype(CreateDXGIFactory
)* createDXGIFactory
=
759 (decltype(CreateDXGIFactory
)*)GetProcAddress(dxgiModule
,
760 "CreateDXGIFactory");
762 if (createDXGIFactory
) {
763 RefPtr
<IDXGIFactory
> factory
= nullptr;
764 createDXGIFactory(__uuidof(IDXGIFactory
), (void**)(&factory
));
766 RefPtr
<IDXGIAdapter
> adapter
;
767 if (SUCCEEDED(factory
->EnumAdapters(0, getter_AddRefs(adapter
)))) {
768 DXGI_ADAPTER_DESC desc
;
770 if (SUCCEEDED(adapter
->GetDesc(&desc
))) {
771 if (desc
.VendorId
!= adapterVendorID
[0] &&
772 desc
.DeviceId
!= adapterDeviceID
[0] &&
773 desc
.VendorId
== adapterVendorID
[1] &&
774 desc
.DeviceId
== adapterDeviceID
[1]) {
783 mHasDriverVersionMismatch
= false;
784 if (mAdapterVendorID
[mActiveGPUIndex
] ==
785 GfxDriverInfo::GetDeviceVendor(DeviceVendor::Intel
)) {
786 // we've had big crashers (bugs 590373 and 595364) apparently correlated
787 // with bad Intel driver installations where the DriverVersion reported
788 // by the registry was not the version of the DLL.
790 // Note that these start without the .dll extension but eventually gain it.
791 bool is64bitApp
= sizeof(void*) == 8;
792 nsAutoString
dllFileName(is64bitApp
? u
"igd10umd64" : u
"igd10umd32");
793 nsAutoString
dllFileName2(is64bitApp
? u
"igd10iumd64" : u
"igd10iumd32");
795 nsString dllVersion
, dllVersion2
;
796 uint64_t dllNumericVersion
= 0, dllNumericVersion2
= 0,
797 driverNumericVersion
= 0, knownSafeMismatchVersion
= 0;
799 // Only parse the DLL version for those found in the driver list
800 nsAutoString eligibleDLLs
;
801 if (NS_SUCCEEDED(GetAdapterDriver(eligibleDLLs
))) {
802 if (FindInReadable(dllFileName
, eligibleDLLs
)) {
803 dllFileName
+= u
".dll"_ns
;
804 gfxWindowsPlatform::GetDLLVersion(dllFileName
.get(), dllVersion
);
805 ParseDriverVersion(dllVersion
, &dllNumericVersion
);
807 if (FindInReadable(dllFileName2
, eligibleDLLs
)) {
808 dllFileName2
+= u
".dll"_ns
;
809 gfxWindowsPlatform::GetDLLVersion(dllFileName2
.get(), dllVersion2
);
810 ParseDriverVersion(dllVersion2
, &dllNumericVersion2
);
814 // Sometimes the DLL is not in the System32 nor SysWOW64 directories. But
815 // UserModeDriverName (or UserModeDriverNameWow, if available) might provide
816 // the full path to the DLL in some DriverStore FileRepository.
817 if (dllNumericVersion
== 0 && dllNumericVersion2
== 0) {
818 nsTArray
<nsString
> eligibleDLLpaths
;
819 const WCHAR
* keyLocation
= mDeviceKey
[mActiveGPUIndex
].get();
820 GetKeyValues(keyLocation
, L
"UserModeDriverName", eligibleDLLpaths
);
821 GetKeyValues(keyLocation
, L
"UserModeDriverNameWow", eligibleDLLpaths
);
822 size_t length
= eligibleDLLpaths
.Length();
824 i
< length
&& dllNumericVersion
== 0 && dllNumericVersion2
== 0;
826 if (FindInReadable(dllFileName
, eligibleDLLpaths
[i
])) {
827 gfxWindowsPlatform::GetDLLVersion(eligibleDLLpaths
[i
].get(),
829 ParseDriverVersion(dllVersion
, &dllNumericVersion
);
830 } else if (FindInReadable(dllFileName2
, eligibleDLLpaths
[i
])) {
831 gfxWindowsPlatform::GetDLLVersion(eligibleDLLpaths
[i
].get(),
833 ParseDriverVersion(dllVersion2
, &dllNumericVersion2
);
838 ParseDriverVersion(mDriverVersion
[mActiveGPUIndex
], &driverNumericVersion
);
839 ParseDriverVersion(u
"9.17.10.0"_ns
, &knownSafeMismatchVersion
);
841 // If there's a driver version mismatch, consider this harmful only when
842 // the driver version is less than knownSafeMismatchVersion. See the
843 // above comment about crashes with old mismatches. If the GetDllVersion
844 // call fails, we are not calling it a mismatch.
845 if ((dllNumericVersion
!= 0 && dllNumericVersion
!= driverNumericVersion
) ||
846 (dllNumericVersion2
!= 0 &&
847 dllNumericVersion2
!= driverNumericVersion
)) {
848 if (driverNumericVersion
< knownSafeMismatchVersion
||
849 std::max(dllNumericVersion
, dllNumericVersion2
) <
850 knownSafeMismatchVersion
) {
851 mHasDriverVersionMismatch
= true;
853 << "Mismatched driver versions between the registry "
854 << NS_ConvertUTF16toUTF8(mDriverVersion
[mActiveGPUIndex
]).get()
855 << " and DLL(s) " << NS_ConvertUTF16toUTF8(dllVersion
).get() << ", "
856 << NS_ConvertUTF16toUTF8(dllVersion2
).get() << " reported.";
858 } else if (dllNumericVersion
== 0 && dllNumericVersion2
== 0) {
859 // Leave it as an asserting error for now, to see if we can find
860 // a system that exhibits this kind of a problem internally.
861 gfxCriticalErrorOnce()
862 << "Potential driver version mismatch ignored due to missing DLLs "
863 << NS_ConvertUTF16toUTF8(dllFileName
).get()
864 << " v=" << NS_ConvertUTF16toUTF8(dllVersion
).get() << " and "
865 << NS_ConvertUTF16toUTF8(dllFileName2
).get()
866 << " v=" << NS_ConvertUTF16toUTF8(dllVersion2
).get();
870 // Get monitor information
873 const char* spoofedDriverVersionString
=
874 PR_GetEnv("MOZ_GFX_SPOOF_DRIVER_VERSION");
875 if (spoofedDriverVersionString
) {
876 mDriverVersion
[mActiveGPUIndex
].AssignASCII(spoofedDriverVersionString
);
879 const char* spoofedVendor
= PR_GetEnv("MOZ_GFX_SPOOF_VENDOR_ID");
881 mAdapterVendorID
[mActiveGPUIndex
].AssignASCII(spoofedVendor
);
884 const char* spoofedDevice
= PR_GetEnv("MOZ_GFX_SPOOF_DEVICE_ID");
886 mAdapterDeviceID
[mActiveGPUIndex
].AssignASCII(spoofedDevice
);
889 AddCrashReportAnnotations();
895 GfxInfo::GetAdapterDescription(nsAString
& aAdapterDescription
) {
896 aAdapterDescription
= mDeviceString
[mActiveGPUIndex
];
901 GfxInfo::GetAdapterDescription2(nsAString
& aAdapterDescription
) {
902 aAdapterDescription
= mDeviceString
[1 - mActiveGPUIndex
];
907 GfxInfo::RefreshMonitors() {
908 mDisplayInfo
.Clear();
910 for (int deviceIndex
= 0;; deviceIndex
++) {
911 DISPLAY_DEVICEW device
;
912 device
.cb
= sizeof(device
);
913 if (!::EnumDisplayDevicesW(nullptr, deviceIndex
, &device
, 0)) {
917 if (!(device
.StateFlags
& DISPLAY_DEVICE_ACTIVE
)) {
922 mode
.dmSize
= sizeof(mode
);
923 mode
.dmDriverExtra
= 0;
924 if (!::EnumDisplaySettingsW(device
.DeviceName
, ENUM_CURRENT_SETTINGS
,
929 DisplayInfo displayInfo
;
931 displayInfo
.mScreenWidth
= mode
.dmPelsWidth
;
932 displayInfo
.mScreenHeight
= mode
.dmPelsHeight
;
933 displayInfo
.mRefreshRate
= mode
.dmDisplayFrequency
;
934 displayInfo
.mIsPseudoDisplay
=
935 !!(device
.StateFlags
& DISPLAY_DEVICE_MIRRORING_DRIVER
);
936 displayInfo
.mDeviceString
= device
.DeviceString
;
938 mDisplayInfo
.AppendElement(displayInfo
);
944 GfxInfo::GetAdapterRAM(uint32_t* aAdapterRAM
) {
946 if (NS_FAILED(GetKeyValue(mDeviceKey
[mActiveGPUIndex
].get(),
947 L
"HardwareInformation.qwMemorySize", result
,
950 if (NS_FAILED(GetKeyValue(mDeviceKey
[mActiveGPUIndex
].get(),
951 L
"HardwareInformation.MemorySize", result
,
956 *aAdapterRAM
= result
;
961 GfxInfo::GetAdapterRAM2(uint32_t* aAdapterRAM
) {
964 if (NS_FAILED(GetKeyValue(mDeviceKey
[1 - mActiveGPUIndex
].get(),
965 L
"HardwareInformation.qwMemorySize", result
,
968 if (NS_FAILED(GetKeyValue(mDeviceKey
[1 - mActiveGPUIndex
].get(),
969 L
"HardwareInformation.MemorySize", result
,
975 *aAdapterRAM
= result
;
980 GfxInfo::GetAdapterDriver(nsAString
& aAdapterDriver
) {
981 if (NS_FAILED(GetKeyValue(mDeviceKey
[mActiveGPUIndex
].get(),
982 L
"InstalledDisplayDrivers", aAdapterDriver
,
984 aAdapterDriver
= L
"Unknown";
989 GfxInfo::GetAdapterDriver2(nsAString
& aAdapterDriver
) {
991 aAdapterDriver
.Truncate();
992 } else if (NS_FAILED(GetKeyValue(mDeviceKey
[1 - mActiveGPUIndex
].get(),
993 L
"InstalledDisplayDrivers", aAdapterDriver
,
995 aAdapterDriver
= L
"Unknown";
1001 GfxInfo::GetAdapterDriverVendor(nsAString
& aAdapterDriverVendor
) {
1002 aAdapterDriverVendor
.Truncate();
1007 GfxInfo::GetAdapterDriverVersion(nsAString
& aAdapterDriverVersion
) {
1008 aAdapterDriverVersion
= mDriverVersion
[mActiveGPUIndex
];
1013 GfxInfo::GetAdapterDriverDate(nsAString
& aAdapterDriverDate
) {
1014 aAdapterDriverDate
= mDriverDate
[mActiveGPUIndex
];
1019 GfxInfo::GetAdapterDriverVendor2(nsAString
& aAdapterDriverVendor
) {
1020 aAdapterDriverVendor
.Truncate();
1025 GfxInfo::GetAdapterDriverVersion2(nsAString
& aAdapterDriverVersion
) {
1026 aAdapterDriverVersion
= mDriverVersion
[1 - mActiveGPUIndex
];
1031 GfxInfo::GetAdapterDriverDate2(nsAString
& aAdapterDriverDate
) {
1032 aAdapterDriverDate
= mDriverDate
[1 - mActiveGPUIndex
];
1037 GfxInfo::GetAdapterVendorID(nsAString
& aAdapterVendorID
) {
1038 aAdapterVendorID
= mAdapterVendorID
[mActiveGPUIndex
];
1043 GfxInfo::GetAdapterVendorID2(nsAString
& aAdapterVendorID
) {
1044 aAdapterVendorID
= mAdapterVendorID
[1 - mActiveGPUIndex
];
1049 GfxInfo::GetAdapterDeviceID(nsAString
& aAdapterDeviceID
) {
1050 aAdapterDeviceID
= mAdapterDeviceID
[mActiveGPUIndex
];
1055 GfxInfo::GetAdapterDeviceID2(nsAString
& aAdapterDeviceID
) {
1056 aAdapterDeviceID
= mAdapterDeviceID
[1 - mActiveGPUIndex
];
1061 GfxInfo::GetAdapterSubsysID(nsAString
& aAdapterSubsysID
) {
1062 aAdapterSubsysID
= mAdapterSubsysID
[mActiveGPUIndex
];
1067 GfxInfo::GetAdapterSubsysID2(nsAString
& aAdapterSubsysID
) {
1068 aAdapterSubsysID
= mAdapterSubsysID
[1 - mActiveGPUIndex
];
1073 GfxInfo::GetIsGPU2Active(bool* aIsGPU2Active
) {
1074 // This is never the case, as the active GPU ends up being
1075 // the first one. It should probably be removed.
1076 *aIsGPU2Active
= false;
1081 GfxInfo::GetDisplayInfo(nsTArray
<nsString
>& aDisplayInfo
) {
1082 for (auto displayInfo
: mDisplayInfo
) {
1084 value
.AppendPrintf("%dx%d@%dHz %s %s", displayInfo
.mScreenWidth
,
1085 displayInfo
.mScreenHeight
, displayInfo
.mRefreshRate
,
1086 displayInfo
.mIsPseudoDisplay
? "Pseudo Display :" : ":",
1087 NS_ConvertUTF16toUTF8(displayInfo
.mDeviceString
).get());
1089 aDisplayInfo
.AppendElement(value
);
1096 GfxInfo::GetDisplayWidth(nsTArray
<uint32_t>& aDisplayWidth
) {
1097 for (auto displayInfo
: mDisplayInfo
) {
1098 aDisplayWidth
.AppendElement((uint32_t)displayInfo
.mScreenWidth
);
1104 GfxInfo::GetDisplayHeight(nsTArray
<uint32_t>& aDisplayHeight
) {
1105 for (auto displayInfo
: mDisplayInfo
) {
1106 aDisplayHeight
.AppendElement((uint32_t)displayInfo
.mScreenHeight
);
1112 GfxInfo::GetDrmRenderDevice(nsACString
& aDrmRenderDevice
) {
1113 return NS_ERROR_NOT_IMPLEMENTED
;
1116 /* Cisco's VPN software can cause corruption of the floating point state.
1117 * Make a note of this in our crash reports so that some weird crashes
1118 * make more sense */
1119 static void CheckForCiscoVPN() {
1122 /* This will give false positives, but hopefully no false negatives */
1124 RegOpenKeyExW(HKEY_LOCAL_MACHINE
, L
"Software\\Cisco Systems\\VPN Client",
1125 0, KEY_QUERY_VALUE
, &key
);
1126 if (result
== ERROR_SUCCESS
) {
1128 CrashReporter::AppendAppNotesToCrashReport("Cisco VPN\n"_ns
);
1132 void GfxInfo::AddCrashReportAnnotations() {
1135 if (mHasDriverVersionMismatch
) {
1136 CrashReporter::AppendAppNotesToCrashReport("DriverVersionMismatch\n"_ns
);
1139 nsString deviceID
, vendorID
, driverVersion
, subsysID
;
1140 nsCString narrowDeviceID
, narrowVendorID
, narrowDriverVersion
, narrowSubsysID
;
1142 GetAdapterDeviceID(deviceID
);
1143 CopyUTF16toUTF8(deviceID
, narrowDeviceID
);
1144 GetAdapterVendorID(vendorID
);
1145 CopyUTF16toUTF8(vendorID
, narrowVendorID
);
1146 GetAdapterDriverVersion(driverVersion
);
1147 CopyUTF16toUTF8(driverVersion
, narrowDriverVersion
);
1148 GetAdapterSubsysID(subsysID
);
1149 CopyUTF16toUTF8(subsysID
, narrowSubsysID
);
1151 CrashReporter::AnnotateCrashReport(CrashReporter::Annotation::AdapterVendorID
,
1153 CrashReporter::AnnotateCrashReport(CrashReporter::Annotation::AdapterDeviceID
,
1155 CrashReporter::AnnotateCrashReport(
1156 CrashReporter::Annotation::AdapterDriverVersion
, narrowDriverVersion
);
1157 CrashReporter::AnnotateCrashReport(CrashReporter::Annotation::AdapterSubsysID
,
1160 /* Add an App Note, this contains extra information. */
1163 // TODO: We should probably convert this into a proper annotation
1164 if (vendorID
== GfxDriverInfo::GetDeviceVendor(DeviceVendor::All
)) {
1165 /* if we didn't find a valid vendorID lets append the mDeviceID string to
1166 * try to find out why */
1167 LossyAppendUTF16toASCII(mDeviceID
[mActiveGPUIndex
], note
);
1168 note
.AppendLiteral(", ");
1169 LossyAppendUTF16toASCII(mDeviceKeyDebug
, note
);
1171 note
.AppendLiteral("\n");
1174 nsString deviceID2
, vendorID2
, subsysID2
;
1175 nsAutoString adapterDriverVersionString2
;
1176 nsCString narrowDeviceID2
, narrowVendorID2
, narrowSubsysID2
;
1178 // Make a slight difference between the two cases so that we
1179 // can see it in the crash reports. It may come in handy.
1180 if (mActiveGPUIndex
== 1) {
1181 note
.AppendLiteral("Has dual GPUs. GPU-#2: ");
1183 note
.AppendLiteral("Has dual GPUs. GPU #2: ");
1185 GetAdapterDeviceID2(deviceID2
);
1186 CopyUTF16toUTF8(deviceID2
, narrowDeviceID2
);
1187 GetAdapterVendorID2(vendorID2
);
1188 CopyUTF16toUTF8(vendorID2
, narrowVendorID2
);
1189 GetAdapterDriverVersion2(adapterDriverVersionString2
);
1190 GetAdapterSubsysID(subsysID2
);
1191 CopyUTF16toUTF8(subsysID2
, narrowSubsysID2
);
1192 note
.AppendLiteral("AdapterVendorID2: ");
1193 note
.Append(narrowVendorID2
);
1194 note
.AppendLiteral(", AdapterDeviceID2: ");
1195 note
.Append(narrowDeviceID2
);
1196 note
.AppendLiteral(", AdapterSubsysID2: ");
1197 note
.Append(narrowSubsysID2
);
1198 note
.AppendLiteral(", AdapterDriverVersion2: ");
1199 note
.Append(NS_LossyConvertUTF16toASCII(adapterDriverVersionString2
));
1201 CrashReporter::AppendAppNotesToCrashReport(note
);
1204 static OperatingSystem
WindowsVersionToOperatingSystem(
1205 int32_t aWindowsVersion
) {
1206 switch (aWindowsVersion
) {
1208 return OperatingSystem::Windows7
;
1210 return OperatingSystem::Windows8
;
1212 return OperatingSystem::Windows8_1
;
1214 return OperatingSystem::Windows10
;
1215 case kWindowsUnknown
:
1217 return OperatingSystem::Unknown
;
1221 static bool OnlyAllowFeatureOnWhitelistedVendor(int32_t aFeature
) {
1223 // The GPU process doesn't need hardware acceleration and can run on
1224 // devices that we normally block from not being on our whitelist.
1225 case nsIGfxInfo::FEATURE_GPU_PROCESS
:
1226 // We can mostly assume that ANGLE will work
1227 case nsIGfxInfo::FEATURE_DIRECT3D_11_ANGLE
:
1228 // Software WebRender is our Basic compositor replacement. It needs to
1230 case nsIGfxInfo::FEATURE_WEBRENDER_SOFTWARE
:
1237 // Return true if the CPU supports AVX, but the operating system does not.
1239 static inline bool DetectBrokenAVX() {
1243 // Level not supported.
1249 const unsigned AVX
= 1u << 28;
1250 const unsigned XSAVE
= 1u << 26;
1251 if ((regs
[2] & (AVX
| XSAVE
)) != (AVX
| XSAVE
)) {
1252 // AVX is not supported on this CPU.
1256 const unsigned OSXSAVE
= 1u << 27;
1257 if ((regs
[2] & OSXSAVE
) != OSXSAVE
) {
1258 // AVX is supported, but the OS didn't enable it.
1259 // This can be forced via bcdedit /set xsavedisable 1.
1263 const unsigned AVX_CTRL_BITS
= (1 << 1) | (1 << 2);
1264 return (xgetbv(0) & AVX_CTRL_BITS
) != AVX_CTRL_BITS
;
1268 const nsTArray
<GfxDriverInfo
>& GfxInfo::GetGfxDriverInfo() {
1269 if (!sDriverInfo
->Length()) {
1271 * It should be noted here that more specialized rules on certain features
1272 * should be inserted -before- more generalized restriction. As the first
1273 * match for feature/OS/device found in the list will be used for the final
1274 * blocklisting call.
1281 * The last 5 digit of the NVIDIA driver version maps to the version that
1282 * NVIDIA uses. The minor version (15, 16, 17) corresponds roughtly to the
1283 * OS (Vista, Win7, Win7) but they show up in smaller numbers across all
1284 * OS versions (perhaps due to OS upgrades). So we want to support
1285 * October 2009+ drivers across all these minor versions.
1287 * 187.45 (late October 2009) and earlier contain a bug which can cause us
1288 * to crash on shutdown.
1290 APPEND_TO_DRIVER_BLOCKLIST(
1291 OperatingSystem::Windows7
, DeviceFamily::NvidiaAll
,
1292 GfxDriverInfo::allFeatures
, nsIGfxInfo::FEATURE_BLOCKED_DRIVER_VERSION
,
1293 DRIVER_LESS_THAN_OR_EQUAL
, V(8, 15, 11, 8745),
1294 "FEATURE_FAILURE_NV_W7_15", "nVidia driver > 187.45");
1295 APPEND_TO_DRIVER_BLOCKLIST_RANGE(
1296 OperatingSystem::Windows7
, DeviceFamily::NvidiaAll
,
1297 GfxDriverInfo::allFeatures
, nsIGfxInfo::FEATURE_BLOCKED_DRIVER_VERSION
,
1298 DRIVER_BETWEEN_INCLUSIVE_START
, V(8, 16, 10, 0000), V(8, 16, 11, 8745),
1299 "FEATURE_FAILURE_NV_W7_16", "nVidia driver > 187.45");
1300 // Telemetry doesn't show any driver in this range so it might not even be
1302 APPEND_TO_DRIVER_BLOCKLIST_RANGE(
1303 OperatingSystem::Windows7
, DeviceFamily::NvidiaAll
,
1304 GfxDriverInfo::allFeatures
, nsIGfxInfo::FEATURE_BLOCKED_DRIVER_VERSION
,
1305 DRIVER_BETWEEN_INCLUSIVE_START
, V(8, 17, 10, 0000), V(8, 17, 11, 8745),
1306 "FEATURE_FAILURE_NV_W7_17", "nVidia driver > 187.45");
1309 * AMD/ATI entries. 8.56.1.15 is the driver that shipped with Windows 7 RTM
1311 APPEND_TO_DRIVER_BLOCKLIST(
1312 OperatingSystem::Windows
, DeviceFamily::AtiAll
,
1313 GfxDriverInfo::allFeatures
, nsIGfxInfo::FEATURE_BLOCKED_DRIVER_VERSION
,
1314 DRIVER_LESS_THAN
, V(8, 56, 1, 15), "FEATURE_FAILURE_AMD1", "8.56.1.15");
1317 APPEND_TO_DRIVER_BLOCKLIST2(
1318 OperatingSystem::Windows7
, DeviceFamily::AtiAll
,
1319 GfxDriverInfo::allFeatures
, nsIGfxInfo::FEATURE_BLOCKED_DRIVER_VERSION
,
1320 DRIVER_EQUAL
, V(8, 832, 0, 0), "FEATURE_FAILURE_BUG_1099252");
1323 APPEND_TO_DRIVER_BLOCKLIST2(
1324 OperatingSystem::Windows7
, DeviceFamily::AtiAll
,
1325 GfxDriverInfo::allFeatures
, nsIGfxInfo::FEATURE_BLOCKED_DRIVER_VERSION
,
1326 DRIVER_EQUAL
, V(8, 783, 2, 2000), "FEATURE_FAILURE_BUG_1118695");
1330 // There are a several reports of strange rendering corruptions with this
1331 // driver version, with and without webrender. We weren't able to
1332 // reproduce these problems, but the users were able to update their
1333 // drivers and it went away. So just to be safe, let's blocklist all
1334 // gpu use with this particular (very old) driver, restricted
1335 // to Win10 since we only have reports from that platform.
1336 APPEND_TO_DRIVER_BLOCKLIST2(
1337 OperatingSystem::Windows10
, DeviceFamily::AtiAll
,
1338 GfxDriverInfo::allFeatures
, nsIGfxInfo::FEATURE_BLOCKED_DRIVER_VERSION
,
1339 DRIVER_EQUAL
, V(22, 19, 162, 4), "FEATURE_FAILURE_BUG_1587155");
1342 APPEND_TO_DRIVER_BLOCKLIST_RANGE(
1343 OperatingSystem::Windows
, DeviceFamily::AtiAll
,
1344 nsIGfxInfo::FEATURE_HARDWARE_VIDEO_DECODING
,
1345 nsIGfxInfo::FEATURE_BLOCKED_DRIVER_VERSION
, DRIVER_BETWEEN_INCLUSIVE
,
1346 V(15, 200, 0, 0), V(15, 200, 1062, 1004), "FEATURE_FAILURE_BUG_1198815",
1347 "15.200.0.0-15.200.1062.1004");
1350 APPEND_TO_DRIVER_BLOCKLIST_RANGE(
1351 OperatingSystem::Windows10
, DeviceFamily::AtiAll
,
1352 nsIGfxInfo::FEATURE_HARDWARE_VIDEO_DECODING
,
1353 nsIGfxInfo::FEATURE_BLOCKED_DRIVER_VERSION
, DRIVER_BETWEEN_INCLUSIVE
,
1354 V(15, 200, 0, 0), V(15, 301, 2301, 1002), "FEATURE_FAILURE_BUG_1267970",
1355 "15.200.0.0-15.301.2301.1002");
1356 APPEND_TO_DRIVER_BLOCKLIST_RANGE(
1357 OperatingSystem::Windows10
, DeviceFamily::AtiAll
,
1358 nsIGfxInfo::FEATURE_HARDWARE_VIDEO_DECODING
,
1359 nsIGfxInfo::FEATURE_BLOCKED_DRIVER_VERSION
, DRIVER_BETWEEN_INCLUSIVE
,
1360 V(16, 100, 0, 0), V(16, 300, 2311, 0), "FEATURE_FAILURE_BUG_1267970",
1361 "16.100.0.0-16.300.2311.0");
1364 * Bug 783517 - crashes in AMD driver on Windows 8
1366 APPEND_TO_DRIVER_BLOCKLIST_RANGE(
1367 OperatingSystem::Windows8
, DeviceFamily::AtiAll
,
1368 GfxDriverInfo::allFeatures
, nsIGfxInfo::FEATURE_BLOCKED_DRIVER_VERSION
,
1369 DRIVER_BETWEEN_INCLUSIVE_START
, V(8, 982, 0, 0), V(8, 983, 0, 0),
1370 "FEATURE_FAILURE_BUG_783517_AMD", "!= 8.982.*.*");
1373 * Bug 1599981 - crashes in AMD driver on Windows 10
1375 APPEND_TO_DRIVER_BLOCKLIST2(
1376 OperatingSystem::Windows10
, DeviceFamily::RadeonCaicos
,
1377 nsIGfxInfo::FEATURE_DIRECT3D_11_LAYERS
,
1378 nsIGfxInfo::FEATURE_BLOCKED_DRIVER_VERSION
, DRIVER_LESS_THAN
,
1379 V(15, 301, 1901, 0), "FEATURE_FAILURE_BUG_1599981");
1381 /* OpenGL on any ATI/AMD hardware is discouraged
1383 * bug 619773 - WebGL: Crash with blue screen : "NMI: Parity Check / Memory
1384 * Parity Error" bugs 584403, 584404, 620924 - crashes in atioglxx
1385 * + many complaints about incorrect rendering
1387 APPEND_TO_DRIVER_BLOCKLIST2(
1388 OperatingSystem::Windows
, DeviceFamily::AtiAll
,
1389 nsIGfxInfo::FEATURE_OPENGL_LAYERS
, nsIGfxInfo::FEATURE_DISCOURAGED
,
1390 DRIVER_LESS_THAN
, GfxDriverInfo::allDriverVersions
,
1391 "FEATURE_FAILURE_OGL_ATI_DIS");
1397 /* The driver versions used here come from bug 594877. They might not
1398 * be particularly relevant anymore.
1400 #define IMPLEMENT_INTEL_DRIVER_BLOCKLIST(winVer, devFamily, driverVer, ruleId) \
1401 APPEND_TO_DRIVER_BLOCKLIST2(winVer, devFamily, GfxDriverInfo::allFeatures, \
1402 nsIGfxInfo::FEATURE_BLOCKED_DRIVER_VERSION, \
1403 DRIVER_LESS_THAN, driverVer, ruleId)
1405 #define IMPLEMENT_INTEL_DRIVER_BLOCKLIST_D2D(winVer, devFamily, driverVer, \
1407 APPEND_TO_DRIVER_BLOCKLIST2(winVer, devFamily, nsIGfxInfo::FEATURE_DIRECT2D, \
1408 nsIGfxInfo::FEATURE_BLOCKED_DRIVER_VERSION, \
1409 DRIVER_BUILD_ID_LESS_THAN, driverVer, ruleId)
1411 IMPLEMENT_INTEL_DRIVER_BLOCKLIST_D2D(OperatingSystem::Windows7
,
1412 DeviceFamily::IntelGMA500
, 2026,
1413 "FEATURE_FAILURE_594877_7");
1414 IMPLEMENT_INTEL_DRIVER_BLOCKLIST_D2D(
1415 OperatingSystem::Windows7
, DeviceFamily::IntelGMA900
,
1416 GfxDriverInfo::allDriverVersions
, "FEATURE_FAILURE_594877_8");
1417 IMPLEMENT_INTEL_DRIVER_BLOCKLIST_D2D(OperatingSystem::Windows7
,
1418 DeviceFamily::IntelGMA950
, 1930,
1419 "FEATURE_FAILURE_594877_9");
1420 IMPLEMENT_INTEL_DRIVER_BLOCKLIST_D2D(OperatingSystem::Windows7
,
1421 DeviceFamily::IntelGMA3150
, 2117,
1422 "FEATURE_FAILURE_594877_10");
1423 IMPLEMENT_INTEL_DRIVER_BLOCKLIST_D2D(OperatingSystem::Windows7
,
1424 DeviceFamily::IntelGMAX3000
, 1930,
1425 "FEATURE_FAILURE_594877_11");
1426 IMPLEMENT_INTEL_DRIVER_BLOCKLIST_D2D(
1427 OperatingSystem::Windows7
, DeviceFamily::IntelHDGraphicsToSandyBridge
,
1428 2202, "FEATURE_FAILURE_594877_12");
1430 /* Disable Direct2D on Intel GMAX4500 devices because of rendering
1431 * corruption discovered in bug 1180379. These seems to affect even the most
1432 * recent drivers. We're black listing all of the devices to be safe even
1433 * though we've only confirmed the issue on the G45
1435 APPEND_TO_DRIVER_BLOCKLIST2(
1436 OperatingSystem::Windows
, DeviceFamily::IntelGMAX4500HD
,
1437 nsIGfxInfo::FEATURE_DIRECT2D
, nsIGfxInfo::FEATURE_BLOCKED_DEVICE
,
1438 DRIVER_LESS_THAN
, GfxDriverInfo::allDriverVersions
,
1439 "FEATURE_FAILURE_1180379");
1441 IMPLEMENT_INTEL_DRIVER_BLOCKLIST(
1442 OperatingSystem::Windows7
, DeviceFamily::IntelGMA500
, V(5, 0, 0, 2026),
1443 "FEATURE_FAILURE_INTEL_16");
1444 IMPLEMENT_INTEL_DRIVER_BLOCKLIST(
1445 OperatingSystem::Windows7
, DeviceFamily::IntelGMA900
,
1446 GfxDriverInfo::allDriverVersions
, "FEATURE_FAILURE_INTEL_17");
1447 IMPLEMENT_INTEL_DRIVER_BLOCKLIST(
1448 OperatingSystem::Windows7
, DeviceFamily::IntelGMA950
,
1449 V(8, 15, 10, 1930), "FEATURE_FAILURE_INTEL_18");
1450 IMPLEMENT_INTEL_DRIVER_BLOCKLIST(
1451 OperatingSystem::Windows7
, DeviceFamily::IntelGMA3150
,
1452 V(8, 14, 10, 1972), "FEATURE_FAILURE_INTEL_19");
1453 IMPLEMENT_INTEL_DRIVER_BLOCKLIST(
1454 OperatingSystem::Windows7
, DeviceFamily::IntelGMAX3000
,
1455 V(7, 15, 10, 1666), "FEATURE_FAILURE_INTEL_20");
1456 IMPLEMENT_INTEL_DRIVER_BLOCKLIST(
1457 OperatingSystem::Windows7
, DeviceFamily::IntelGMAX4500HD
,
1458 V(7, 15, 10, 1666), "FEATURE_FAILURE_INTEL_21");
1459 IMPLEMENT_INTEL_DRIVER_BLOCKLIST(
1460 OperatingSystem::Windows7
, DeviceFamily::IntelHDGraphicsToSandyBridge
,
1461 V(7, 15, 10, 1666), "FEATURE_FAILURE_INTEL_22");
1464 APPEND_TO_DRIVER_BLOCKLIST(
1465 OperatingSystem::Windows7
, DeviceFamily::IntelGMAX4500HD
,
1466 GfxDriverInfo::allFeatures
, nsIGfxInfo::FEATURE_BLOCKED_DRIVER_VERSION
,
1467 DRIVER_EQUAL
, V(8, 15, 10, 1749), "FEATURE_FAILURE_BUG_1074378_1",
1469 APPEND_TO_DRIVER_BLOCKLIST(
1470 OperatingSystem::Windows7
, DeviceFamily::IntelHDGraphicsToSandyBridge
,
1471 GfxDriverInfo::allFeatures
, nsIGfxInfo::FEATURE_BLOCKED_DRIVER_VERSION
,
1472 DRIVER_EQUAL
, V(8, 15, 10, 1749), "FEATURE_FAILURE_BUG_1074378_2",
1475 /* OpenGL on any Intel hardware is discouraged */
1476 APPEND_TO_DRIVER_BLOCKLIST2(
1477 OperatingSystem::Windows
, DeviceFamily::IntelAll
,
1478 nsIGfxInfo::FEATURE_OPENGL_LAYERS
, nsIGfxInfo::FEATURE_DISCOURAGED
,
1479 DRIVER_LESS_THAN
, GfxDriverInfo::allDriverVersions
,
1480 "FEATURE_FAILURE_INTEL_OGL_DIS");
1483 * Disable acceleration on Intel HD 3000 for graphics drivers
1484 * <= 8.15.10.2321. See bug 1018278 and bug 1060736.
1486 APPEND_TO_DRIVER_BLOCKLIST(
1487 OperatingSystem::Windows
, DeviceFamily::IntelSandyBridge
,
1488 GfxDriverInfo::allFeatures
, nsIGfxInfo::FEATURE_BLOCKED_DRIVER_VERSION
,
1489 DRIVER_BUILD_ID_LESS_THAN_OR_EQUAL
, 2321, "FEATURE_FAILURE_BUG_1018278",
1493 * Disable D2D on Win7 on Intel Haswell for graphics drivers build id <=
1494 * 4578. See bug 1432610
1496 APPEND_TO_DRIVER_BLOCKLIST2(OperatingSystem::Windows7
,
1497 DeviceFamily::IntelHaswell
,
1498 nsIGfxInfo::FEATURE_DIRECT2D
,
1499 nsIGfxInfo::FEATURE_BLOCKED_DRIVER_VERSION
,
1500 DRIVER_BUILD_ID_LESS_THAN_OR_EQUAL
, 4578,
1501 "FEATURE_FAILURE_BUG_1432610");
1503 /* Disable D2D on Win7 on Intel HD Graphics on driver <= 8.15.10.2302
1506 APPEND_TO_DRIVER_BLOCKLIST2(
1507 OperatingSystem::Windows7
, DeviceFamily::IntelMobileHDGraphics
,
1508 nsIGfxInfo::FEATURE_DIRECT2D
,
1509 nsIGfxInfo::FEATURE_BLOCKED_DRIVER_VERSION
, DRIVER_LESS_THAN_OR_EQUAL
,
1510 V(8, 15, 10, 2302), "FEATURE_FAILURE_BUG_806786");
1512 /* Disable D2D on Win8 on Intel HD Graphics on driver <= 8.15.10.2302
1513 * See bug 804144 and 863683
1515 APPEND_TO_DRIVER_BLOCKLIST2(
1516 OperatingSystem::Windows8
, DeviceFamily::IntelMobileHDGraphics
,
1517 nsIGfxInfo::FEATURE_DIRECT2D
,
1518 nsIGfxInfo::FEATURE_BLOCKED_DRIVER_VERSION
, DRIVER_LESS_THAN_OR_EQUAL
,
1519 V(8, 15, 10, 2302), "FEATURE_FAILURE_BUG_804144");
1521 /* Disable D2D on Win7 on Intel HD Graphics on driver == 8.15.10.2418
1524 APPEND_TO_DRIVER_BLOCKLIST2(
1525 OperatingSystem::Windows7
, DeviceFamily::IntelHDGraphicsToSandyBridge
,
1526 nsIGfxInfo::FEATURE_DIRECT2D
,
1527 nsIGfxInfo::FEATURE_BLOCKED_DRIVER_VERSION
, DRIVER_EQUAL
,
1528 V(8, 15, 10, 2418), "FEATURE_FAILURE_BUG_1433790");
1530 /* Disable D3D11 layers on Intel G41 express graphics and Intel GM965, Intel
1531 * X3100, for causing device resets. See bug 1116812.
1533 APPEND_TO_DRIVER_BLOCKLIST2(
1534 OperatingSystem::Windows
, DeviceFamily::Bug1116812
,
1535 nsIGfxInfo::FEATURE_DIRECT3D_11_LAYERS
,
1536 nsIGfxInfo::FEATURE_BLOCKED_DEVICE
, DRIVER_LESS_THAN
,
1537 GfxDriverInfo::allDriverVersions
, "FEATURE_FAILURE_BUG_1116812");
1539 /* Disable D3D11 layers on Intel GMA 3150 for failing to allocate a shared
1540 * handle for textures. See bug 1207665. Additionally block D2D so we don't
1541 * accidentally use WARP.
1543 APPEND_TO_DRIVER_BLOCKLIST2(
1544 OperatingSystem::Windows
, DeviceFamily::Bug1207665
,
1545 nsIGfxInfo::FEATURE_DIRECT3D_11_LAYERS
,
1546 nsIGfxInfo::FEATURE_BLOCKED_DEVICE
, DRIVER_LESS_THAN
,
1547 GfxDriverInfo::allDriverVersions
, "FEATURE_FAILURE_BUG_1207665_1");
1548 APPEND_TO_DRIVER_BLOCKLIST2(
1549 OperatingSystem::Windows
, DeviceFamily::Bug1207665
,
1550 nsIGfxInfo::FEATURE_DIRECT2D
, nsIGfxInfo::FEATURE_BLOCKED_DEVICE
,
1551 DRIVER_LESS_THAN
, GfxDriverInfo::allDriverVersions
,
1552 "FEATURE_FAILURE_BUG_1207665_2");
1554 APPEND_TO_DRIVER_BLOCKLIST2(
1555 OperatingSystem::Windows10
, DeviceFamily::QualcommAll
,
1556 nsIGfxInfo::FEATURE_DIRECT2D
,
1557 nsIGfxInfo::FEATURE_BLOCKED_DRIVER_VERSION
, DRIVER_LESS_THAN
,
1558 GfxDriverInfo::allDriverVersions
, "FEATURE_FAILURE_QUALCOMM");
1560 // Bug 1548410. Disable hardware accelerated video decoding on
1561 // Qualcomm drivers used on Windows on ARM64 which are known to
1562 // cause BSOD's and output suprious green frames while decoding video.
1563 // Bug 1592826 expands the blocklist.
1564 APPEND_TO_DRIVER_BLOCKLIST2(
1565 OperatingSystem::Windows10
, DeviceFamily::QualcommAll
,
1566 nsIGfxInfo::FEATURE_HARDWARE_VIDEO_DECODING
,
1567 nsIGfxInfo::FEATURE_BLOCKED_DRIVER_VERSION
, DRIVER_LESS_THAN_OR_EQUAL
,
1568 V(25, 18, 10440, 0), "FEATURE_FAILURE_BUG_1592826");
1570 /* Disable D2D on AMD Catalyst 14.4 until 14.6
1573 APPEND_TO_DRIVER_BLOCKLIST_RANGE(
1574 OperatingSystem::Windows
, DeviceFamily::AtiAll
,
1575 nsIGfxInfo::FEATURE_DIRECT2D
,
1576 nsIGfxInfo::FEATURE_BLOCKED_DRIVER_VERSION
,
1577 DRIVER_BETWEEN_INCLUSIVE_START
, V(14, 1, 0, 0), V(14, 2, 0, 0),
1578 "FEATURE_FAILURE_BUG_984488_1", "ATI Catalyst 14.6+");
1580 /* Disable D3D9 layers on NVIDIA 6100/6150/6200 series due to glitches
1581 * whilst scrolling. See bugs: 612007, 644787 & 645872.
1583 APPEND_TO_DRIVER_BLOCKLIST2(
1584 OperatingSystem::Windows
, DeviceFamily::NvidiaBlockD3D9Layers
,
1585 nsIGfxInfo::FEATURE_DIRECT3D_9_LAYERS
,
1586 nsIGfxInfo::FEATURE_BLOCKED_DEVICE
, DRIVER_LESS_THAN
,
1587 GfxDriverInfo::allDriverVersions
, "FEATURE_FAILURE_BUG_612007");
1589 /* Microsoft RemoteFX; blocked less than 6.2.0.0 */
1590 APPEND_TO_DRIVER_BLOCKLIST(
1591 OperatingSystem::Windows
, DeviceFamily::MicrosoftAll
,
1592 GfxDriverInfo::allFeatures
, nsIGfxInfo::FEATURE_BLOCKED_DRIVER_VERSION
,
1593 DRIVER_LESS_THAN
, V(6, 2, 0, 0), "< 6.2.0.0",
1594 "FEATURE_FAILURE_REMOTE_FX");
1596 /* Bug 1008759: Optimus (NVidia) crash. Disable D2D on NV 310M. */
1597 APPEND_TO_DRIVER_BLOCKLIST2(
1598 OperatingSystem::Windows
, DeviceFamily::Nvidia310M
,
1599 nsIGfxInfo::FEATURE_DIRECT2D
, nsIGfxInfo::FEATURE_BLOCKED_DEVICE
,
1600 DRIVER_LESS_THAN
, GfxDriverInfo::allDriverVersions
,
1601 "FEATURE_FAILURE_BUG_1008759");
1603 /* Bug 1139503: DXVA crashes with ATI cards on windows 10. */
1604 APPEND_TO_DRIVER_BLOCKLIST2(
1605 OperatingSystem::Windows10
, DeviceFamily::AtiAll
,
1606 nsIGfxInfo::FEATURE_HARDWARE_VIDEO_DECODING
,
1607 nsIGfxInfo::FEATURE_BLOCKED_DRIVER_VERSION
, DRIVER_EQUAL
,
1608 V(15, 200, 1006, 0), "FEATURE_FAILURE_BUG_1139503");
1610 /* Bug 1213107: D3D9 crashes with ATI cards on Windows 7. */
1611 APPEND_TO_DRIVER_BLOCKLIST_RANGE(
1612 OperatingSystem::Windows7
, DeviceFamily::AtiAll
,
1613 nsIGfxInfo::FEATURE_HARDWARE_VIDEO_DECODING
,
1614 nsIGfxInfo::FEATURE_BLOCKED_DRIVER_VERSION
, DRIVER_BETWEEN_INCLUSIVE
,
1615 V(8, 861, 0, 0), V(8, 862, 6, 5000), "FEATURE_FAILURE_BUG_1213107_1",
1616 "Radeon driver > 8.862.6.5000");
1617 APPEND_TO_DRIVER_BLOCKLIST_RANGE(
1618 OperatingSystem::Windows7
, DeviceFamily::AtiAll
,
1619 nsIGfxInfo::FEATURE_WEBGL_ANGLE
,
1620 nsIGfxInfo::FEATURE_BLOCKED_DRIVER_VERSION
, DRIVER_BETWEEN_INCLUSIVE
,
1621 V(8, 861, 0, 0), V(8, 862, 6, 5000), "FEATURE_FAILURE_BUG_1213107_2",
1622 "Radeon driver > 8.862.6.5000");
1624 /* This may not be needed at all */
1625 APPEND_TO_DRIVER_BLOCKLIST2(
1626 OperatingSystem::Windows7
, DeviceFamily::Bug1155608
,
1627 nsIGfxInfo::FEATURE_HARDWARE_VIDEO_DECODING
,
1628 nsIGfxInfo::FEATURE_BLOCKED_DRIVER_VERSION
, DRIVER_LESS_THAN
,
1629 V(8, 15, 10, 2869), "FEATURE_FAILURE_INTEL_W7_HW_DECODING");
1631 /* Bug 1203199/1092166: DXVA startup crashes on some intel drivers. */
1632 APPEND_TO_DRIVER_BLOCKLIST(OperatingSystem::Windows
, DeviceFamily::IntelAll
,
1633 nsIGfxInfo::FEATURE_HARDWARE_VIDEO_DECODING
,
1634 nsIGfxInfo::FEATURE_BLOCKED_DRIVER_VERSION
,
1635 DRIVER_BUILD_ID_LESS_THAN_OR_EQUAL
, 2849,
1636 "FEATURE_FAILURE_BUG_1203199_1",
1637 "Intel driver > X.X.X.2849");
1639 APPEND_TO_DRIVER_BLOCKLIST2(
1640 OperatingSystem::Windows
, DeviceFamily::Nvidia8800GTS
,
1641 nsIGfxInfo::FEATURE_HARDWARE_VIDEO_DECODING
,
1642 nsIGfxInfo::FEATURE_BLOCKED_DRIVER_VERSION
, DRIVER_EQUAL
,
1643 V(9, 18, 13, 4052), "FEATURE_FAILURE_BUG_1203199_2");
1645 /* Bug 1137716: XXX this should really check for the matching Intel piece as
1646 * well. Unfortunately, we don't have the infrastructure to do that */
1647 APPEND_TO_DRIVER_BLOCKLIST_RANGE_GPU2(
1648 OperatingSystem::Windows7
, DeviceFamily::Bug1137716
,
1649 GfxDriverInfo::allFeatures
, nsIGfxInfo::FEATURE_BLOCKED_DRIVER_VERSION
,
1650 DRIVER_BETWEEN_INCLUSIVE
, V(8, 17, 12, 5730), V(8, 17, 12, 6901),
1651 "FEATURE_FAILURE_BUG_1137716", "Nvidia driver > 8.17.12.6901");
1653 /* Bug 1153381: WebGL issues with D3D11 ANGLE on Intel. These may be fixed
1654 * by an ANGLE update. */
1655 APPEND_TO_DRIVER_BLOCKLIST2(
1656 OperatingSystem::Windows
, DeviceFamily::IntelGMAX4500HD
,
1657 nsIGfxInfo::FEATURE_DIRECT3D_11_ANGLE
,
1658 nsIGfxInfo::FEATURE_BLOCKED_DEVICE
, DRIVER_LESS_THAN
,
1659 GfxDriverInfo::allDriverVersions
, "FEATURE_FAILURE_BUG_1153381");
1661 /* Bug 1336710: Crash in rx::Blit9::initialize. */
1662 APPEND_TO_DRIVER_BLOCKLIST2(
1663 OperatingSystem::WindowsXP
, DeviceFamily::IntelGMAX4500HD
,
1664 nsIGfxInfo::FEATURE_WEBGL_ANGLE
, nsIGfxInfo::FEATURE_BLOCKED_DEVICE
,
1665 DRIVER_LESS_THAN
, GfxDriverInfo::allDriverVersions
,
1666 "FEATURE_FAILURE_BUG_1336710");
1668 APPEND_TO_DRIVER_BLOCKLIST2(
1669 OperatingSystem::WindowsXP
, DeviceFamily::IntelHDGraphicsToSandyBridge
,
1670 nsIGfxInfo::FEATURE_WEBGL_ANGLE
, nsIGfxInfo::FEATURE_BLOCKED_DEVICE
,
1671 DRIVER_LESS_THAN
, GfxDriverInfo::allDriverVersions
,
1672 "FEATURE_FAILURE_BUG_1336710");
1674 /* Bug 1304360: Graphical artifacts with D3D9 on Windows 7. */
1675 APPEND_TO_DRIVER_BLOCKLIST2(OperatingSystem::Windows7
,
1676 DeviceFamily::IntelGMAX3000
,
1677 nsIGfxInfo::FEATURE_DIRECT3D_9_LAYERS
,
1678 nsIGfxInfo::FEATURE_BLOCKED_DRIVER_VERSION
,
1679 DRIVER_BUILD_ID_LESS_THAN_OR_EQUAL
, 1749,
1680 "FEATURE_FAILURE_INTEL_W7_D3D9_LAYERS");
1683 if (DetectBrokenAVX()) {
1684 APPEND_TO_DRIVER_BLOCKLIST2(
1685 OperatingSystem::Windows7
, DeviceFamily::IntelAll
,
1686 nsIGfxInfo::FEATURE_DIRECT3D_11_LAYERS
,
1687 nsIGfxInfo::FEATURE_BLOCKED_DRIVER_VERSION
, DRIVER_LESS_THAN
,
1688 GfxDriverInfo::allDriverVersions
, "FEATURE_FAILURE_BUG_1403353");
1692 ////////////////////////////////////
1695 // Older than 5-15-2016
1696 APPEND_TO_DRIVER_BLOCKLIST2(
1697 OperatingSystem::Windows
, DeviceFamily::AtiAll
,
1698 nsIGfxInfo::FEATURE_WEBGL_OPENGL
, nsIGfxInfo::FEATURE_DISCOURAGED
,
1699 DRIVER_LESS_THAN
, V(16, 200, 1010, 1002), "WEBGL_NATIVE_GL_OLD_AMD");
1701 // Older than 11-18-2015
1702 APPEND_TO_DRIVER_BLOCKLIST2(
1703 OperatingSystem::Windows
, DeviceFamily::IntelAll
,
1704 nsIGfxInfo::FEATURE_WEBGL_OPENGL
, nsIGfxInfo::FEATURE_DISCOURAGED
,
1705 DRIVER_BUILD_ID_LESS_THAN
, 4331, "WEBGL_NATIVE_GL_OLD_INTEL");
1707 // Older than 2-23-2016
1708 APPEND_TO_DRIVER_BLOCKLIST2(
1709 OperatingSystem::Windows
, DeviceFamily::NvidiaAll
,
1710 nsIGfxInfo::FEATURE_WEBGL_OPENGL
, nsIGfxInfo::FEATURE_DISCOURAGED
,
1711 DRIVER_LESS_THAN
, V(10, 18, 13, 6200), "WEBGL_NATIVE_GL_OLD_NVIDIA");
1713 ////////////////////////////////////
1714 // FEATURE_DX_INTEROP2
1717 APPEND_TO_DRIVER_BLOCKLIST2(
1718 OperatingSystem::Windows
, DeviceFamily::AtiAll
,
1719 nsIGfxInfo::FEATURE_DX_INTEROP2
,
1720 nsIGfxInfo::FEATURE_BLOCKED_DRIVER_VERSION
, DRIVER_LESS_THAN
,
1721 GfxDriverInfo::allDriverVersions
, "DX_INTEROP2_AMD_CRASH");
1723 ////////////////////////////////////
1724 // FEATURE_D3D11_KEYED_MUTEX
1727 APPEND_TO_DRIVER_BLOCKLIST2(
1728 OperatingSystem::Windows
, DeviceFamily::IntelHDGraphicsToSandyBridge
,
1729 nsIGfxInfo::FEATURE_D3D11_KEYED_MUTEX
,
1730 nsIGfxInfo::FEATURE_BLOCKED_DEVICE
, DRIVER_LESS_THAN
,
1731 GfxDriverInfo::allDriverVersions
, "FEATURE_FAILURE_BUG_1359416");
1733 // Bug 1447141, for causing device creation crashes.
1734 APPEND_TO_DRIVER_BLOCKLIST2(
1735 OperatingSystem::Windows7
, DeviceFamily::Bug1447141
,
1736 GfxDriverInfo::allFeatures
, nsIGfxInfo::FEATURE_BLOCKED_DEVICE
,
1737 DRIVER_EQUAL
, V(15, 201, 2201, 0), "FEATURE_FAILURE_BUG_1447141_1");
1738 APPEND_TO_DRIVER_BLOCKLIST2(
1739 OperatingSystem::Windows7
, DeviceFamily::Bug1447141
,
1740 GfxDriverInfo::allFeatures
, nsIGfxInfo::FEATURE_BLOCKED_DEVICE
,
1741 DRIVER_EQUAL
, V(15, 201, 1701, 0), "FEATURE_FAILURE_BUG_1447141_1");
1744 APPEND_TO_DRIVER_BLOCKLIST2(
1745 OperatingSystem::Windows
, DeviceFamily::NvidiaAll
,
1746 GfxDriverInfo::allFeatures
, nsIGfxInfo::FEATURE_BLOCKED_DEVICE
,
1747 DRIVER_EQUAL
, V(24, 21, 13, 9731), "FEATURE_FAILURE_BUG_1457758");
1749 ////////////////////////////////////
1753 APPEND_TO_DRIVER_BLOCKLIST2(
1754 OperatingSystem::Windows
, DeviceFamily::IntelHDGraphicsToSandyBridge
,
1755 nsIGfxInfo::FEATURE_DX_NV12
, nsIGfxInfo::FEATURE_BLOCKED_DRIVER_VERSION
,
1756 DRIVER_BUILD_ID_LESS_THAN_OR_EQUAL
, 4459,
1757 "FEATURE_BLOCKED_DRIVER_VERSION");
1759 ////////////////////////////////////
1762 APPEND_TO_DRIVER_BLOCKLIST2(
1763 OperatingSystem::Windows
, DeviceFamily::NvidiaAll
,
1764 nsIGfxInfo::FEATURE_DX_P010
, nsIGfxInfo::FEATURE_BLOCKED_DEVICE
,
1765 DRIVER_LESS_THAN
, GfxDriverInfo::allDriverVersions
,
1766 "FEATURE_UNQUALIFIED_P010_NVIDIA");
1768 ////////////////////////////////////
1769 // FEATURE_WEBRENDER
1770 #ifndef EARLY_BETA_OR_EARLIER
1771 // Block some specific Nvidia cards for being too low-powered.
1772 APPEND_TO_DRIVER_BLOCKLIST2(
1773 OperatingSystem::Windows
, DeviceFamily::NvidiaBlockWebRender
,
1774 nsIGfxInfo::FEATURE_WEBRENDER
, nsIGfxInfo::FEATURE_BLOCKED_DEVICE
,
1775 DRIVER_LESS_THAN
, GfxDriverInfo::allDriverVersions
,
1776 "FEATURE_UNQUALIFIED_WEBRENDER_NVIDIA_BLOCKED");
1779 // Block 8.56.1.15/16
1780 APPEND_TO_DRIVER_BLOCKLIST2(OperatingSystem::Windows
, DeviceFamily::AtiAll
,
1781 nsIGfxInfo::FEATURE_WEBRENDER
,
1782 nsIGfxInfo::FEATURE_BLOCKED_DRIVER_VERSION
,
1783 DRIVER_LESS_THAN_OR_EQUAL
, V(8, 56, 1, 16),
1784 "CRASHY_DRIVERS_BUG_1678808");
1786 ////////////////////////////////////
1787 // FEATURE_WEBRENDER - ALLOWLIST
1788 APPEND_TO_DRIVER_BLOCKLIST2_EXT(
1789 OperatingSystem::Windows
, ScreenSizeStatus::All
, BatteryStatus::All
,
1790 DesktopEnvironment::All
, WindowProtocol::All
, DriverVendor::All
,
1791 DeviceFamily::AmdR600
, nsIGfxInfo::FEATURE_WEBRENDER
,
1792 nsIGfxInfo::FEATURE_ALLOW_ALWAYS
, DRIVER_COMPARISON_IGNORED
,
1793 V(0, 0, 0, 0), "FEATURE_ROLLOUT_AMD_R600");
1795 APPEND_TO_DRIVER_BLOCKLIST2_EXT(
1796 OperatingSystem::Windows
, ScreenSizeStatus::All
, BatteryStatus::All
,
1797 DesktopEnvironment::All
, WindowProtocol::All
, DriverVendor::All
,
1798 DeviceFamily::AtiRolloutWebRender
, nsIGfxInfo::FEATURE_WEBRENDER
,
1799 nsIGfxInfo::FEATURE_ALLOW_ALWAYS
, DRIVER_COMPARISON_IGNORED
,
1800 V(0, 0, 0, 0), "FEATURE_ROLLOUT_DESKTOP_AMD");
1802 APPEND_TO_DRIVER_BLOCKLIST2_EXT(
1803 OperatingSystem::Windows
, ScreenSizeStatus::All
, BatteryStatus::All
,
1804 DesktopEnvironment::All
, WindowProtocol::All
, DriverVendor::All
,
1805 DeviceFamily::NvidiaRolloutWebRender
, nsIGfxInfo::FEATURE_WEBRENDER
,
1806 nsIGfxInfo::FEATURE_ALLOW_ALWAYS
, DRIVER_COMPARISON_IGNORED
,
1807 V(0, 0, 0, 0), "FEATURE_ROLLOUT_NV");
1809 APPEND_TO_DRIVER_BLOCKLIST2_EXT(
1810 OperatingSystem::Windows
, ScreenSizeStatus::All
, BatteryStatus::All
,
1811 DesktopEnvironment::All
, WindowProtocol::All
, DriverVendor::All
,
1812 DeviceFamily::IntelRolloutWebRender
, nsIGfxInfo::FEATURE_WEBRENDER
,
1813 nsIGfxInfo::FEATURE_ALLOW_ALWAYS
, DRIVER_COMPARISON_IGNORED
,
1814 V(0, 0, 0, 0), "FEATURE_ROLLOUT_INTEL");
1816 ////////////////////////////////////
1817 // FEATURE_WEBRENDER_COMPOSITOR
1819 #ifndef EARLY_BETA_OR_EARLIER
1820 // See also bug 161687
1821 APPEND_TO_DRIVER_BLOCKLIST2(
1822 OperatingSystem::Windows
, DeviceFamily::IntelAll
,
1823 nsIGfxInfo::FEATURE_WEBRENDER_COMPOSITOR
,
1824 nsIGfxInfo::FEATURE_BLOCKED_DEVICE
, DRIVER_EQUAL
, V(24, 20, 100, 6293),
1825 "FEATURE_FAILURE_BUG_1602511");
1827 APPEND_TO_DRIVER_BLOCKLIST2(OperatingSystem::Windows
, DeviceFamily::AtiAll
,
1828 nsIGfxInfo::FEATURE_WEBRENDER_COMPOSITOR
,
1829 nsIGfxInfo::FEATURE_BLOCKED_DEVICE
,
1830 DRIVER_LESS_THAN_OR_EQUAL
, V(8, 17, 10, 1129),
1831 "FEATURE_FAILURE_CHROME_BUG_800950");
1834 // WebRender is unable to use scissored clears in some cases
1835 APPEND_TO_DRIVER_BLOCKLIST2(
1836 OperatingSystem::Windows
, DeviceFamily::IntelAll
,
1837 nsIGfxInfo::FEATURE_WEBRENDER_SCISSORED_CACHE_CLEARS
,
1838 nsIGfxInfo::FEATURE_BLOCKED_DEVICE
, DRIVER_COMPARISON_IGNORED
,
1839 V(0, 0, 0, 0), "FEATURE_FAILURE_BUG_1603515");
1841 ////////////////////////////////////
1842 // FEATURE_WEBRENDER_SOFTWARE
1844 // TODO(aosmond): Bug 1678044 - wdspec tests ignore enable/disable-webrender
1845 // Once the test infrastructure is fixed, we can remove this blocklist rule
1846 APPEND_TO_DRIVER_BLOCKLIST2(
1847 OperatingSystem::Windows
, DeviceFamily::AmazonAll
,
1848 nsIGfxInfo::FEATURE_WEBRENDER_SOFTWARE
,
1849 nsIGfxInfo::FEATURE_BLOCKED_DEVICE
, DRIVER_COMPARISON_IGNORED
,
1850 V(0, 0, 0, 0), "FEATURE_FAILURE_BUG_1678044");
1852 ////////////////////////////////////
1853 // FEATURE_WEBRENDER_SOFTWARE - ALLOWLIST
1854 #ifdef EARLY_BETA_OR_EARLIER
1855 # if defined(_M_IX86) || defined(_M_X64) || defined(__i386__) || \
1856 defined(__i386) || defined(__amd64__)
1857 APPEND_TO_DRIVER_BLOCKLIST2(OperatingSystem::Windows
, DeviceFamily::All
,
1858 nsIGfxInfo::FEATURE_WEBRENDER_SOFTWARE
,
1859 nsIGfxInfo::FEATURE_ALLOW_ALWAYS
,
1860 DRIVER_COMPARISON_IGNORED
, V(0, 0, 0, 0),
1861 "FEATURE_ROLLOUT_NIGHTLY_SOFTWARE_WR_S_M_SCRN");
1865 return *sDriverInfo
;
1868 nsresult
GfxInfo::GetFeatureStatusImpl(
1869 int32_t aFeature
, int32_t* aStatus
, nsAString
& aSuggestedDriverVersion
,
1870 const nsTArray
<GfxDriverInfo
>& aDriverInfo
, nsACString
& aFailureId
,
1871 OperatingSystem
* aOS
/* = nullptr */) {
1872 NS_ENSURE_ARG_POINTER(aStatus
);
1873 aSuggestedDriverVersion
.SetIsVoid(true);
1874 OperatingSystem os
= WindowsVersionToOperatingSystem(mWindowsVersion
);
1875 *aStatus
= nsIGfxInfo::FEATURE_STATUS_UNKNOWN
;
1878 if (sShutdownOccurred
) {
1882 // Don't evaluate special cases if we're checking the downloaded blocklist.
1883 if (!aDriverInfo
.Length()) {
1884 nsAutoString adapterVendorID
;
1885 nsAutoString adapterDeviceID
;
1886 nsAutoString adapterDriverVersionString
;
1887 if (NS_FAILED(GetAdapterVendorID(adapterVendorID
)) ||
1888 NS_FAILED(GetAdapterDeviceID(adapterDeviceID
)) ||
1889 NS_FAILED(GetAdapterDriverVersion(adapterDriverVersionString
))) {
1890 aFailureId
= "FEATURE_FAILURE_GET_ADAPTER";
1891 *aStatus
= FEATURE_BLOCKED_DEVICE
;
1895 if (OnlyAllowFeatureOnWhitelistedVendor(aFeature
) &&
1896 !adapterVendorID
.Equals(
1897 GfxDriverInfo::GetDeviceVendor(DeviceVendor::Intel
),
1898 nsCaseInsensitiveStringComparator
) &&
1899 !adapterVendorID
.Equals(
1900 GfxDriverInfo::GetDeviceVendor(DeviceVendor::NVIDIA
),
1901 nsCaseInsensitiveStringComparator
) &&
1902 !adapterVendorID
.Equals(
1903 GfxDriverInfo::GetDeviceVendor(DeviceVendor::ATI
),
1904 nsCaseInsensitiveStringComparator
) &&
1905 !adapterVendorID
.Equals(
1906 GfxDriverInfo::GetDeviceVendor(DeviceVendor::Microsoft
),
1907 nsCaseInsensitiveStringComparator
) &&
1908 !adapterVendorID
.Equals(
1909 GfxDriverInfo::GetDeviceVendor(DeviceVendor::Parallels
),
1910 nsCaseInsensitiveStringComparator
) &&
1911 !adapterVendorID
.Equals(
1912 GfxDriverInfo::GetDeviceVendor(DeviceVendor::Qualcomm
),
1913 nsCaseInsensitiveStringComparator
) &&
1914 // FIXME - these special hex values are currently used in xpcshell tests
1915 // introduced by bug 625160 patch 8/8. Maybe these tests need to be
1916 // adjusted now that we're only whitelisting intel/ati/nvidia.
1917 !adapterVendorID
.LowerCaseEqualsLiteral("0xabcd") &&
1918 !adapterVendorID
.LowerCaseEqualsLiteral("0xdcba") &&
1919 !adapterVendorID
.LowerCaseEqualsLiteral("0xabab") &&
1920 !adapterVendorID
.LowerCaseEqualsLiteral("0xdcdc")) {
1921 if (adapterVendorID
.Equals(
1922 GfxDriverInfo::GetDeviceVendor(DeviceVendor::MicrosoftHyperV
),
1923 nsCaseInsensitiveStringComparator
) ||
1924 adapterVendorID
.Equals(
1925 GfxDriverInfo::GetDeviceVendor(DeviceVendor::VMWare
),
1926 nsCaseInsensitiveStringComparator
) ||
1927 adapterVendorID
.Equals(
1928 GfxDriverInfo::GetDeviceVendor(DeviceVendor::VirtualBox
),
1929 nsCaseInsensitiveStringComparator
)) {
1930 aFailureId
= "FEATURE_FAILURE_VM_VENDOR";
1931 } else if (adapterVendorID
.Equals(GfxDriverInfo::GetDeviceVendor(
1932 DeviceVendor::MicrosoftBasic
),
1933 nsCaseInsensitiveStringComparator
)) {
1934 aFailureId
= "FEATURE_FAILURE_MICROSOFT_BASIC_VENDOR";
1935 } else if (adapterVendorID
.IsEmpty()) {
1936 aFailureId
= "FEATURE_FAILURE_EMPTY_DEVICE_VENDOR";
1938 aFailureId
= "FEATURE_FAILURE_UNKNOWN_DEVICE_VENDOR";
1940 *aStatus
= FEATURE_BLOCKED_DEVICE
;
1944 uint64_t driverVersion
;
1945 if (!ParseDriverVersion(adapterDriverVersionString
, &driverVersion
)) {
1946 aFailureId
= "FEATURE_FAILURE_PARSE_DRIVER";
1947 *aStatus
= FEATURE_BLOCKED_DRIVER_VERSION
;
1951 if (mHasDriverVersionMismatch
) {
1952 *aStatus
= nsIGfxInfo::FEATURE_BLOCKED_MISMATCHED_VERSION
;
1957 return GfxInfoBase::GetFeatureStatusImpl(
1958 aFeature
, aStatus
, aSuggestedDriverVersion
, aDriverInfo
, aFailureId
, &os
);
1961 nsresult
GfxInfo::FindMonitors(JSContext
* aCx
, JS::HandleObject aOutArray
) {
1962 int deviceCount
= 0;
1963 for (auto displayInfo
: mDisplayInfo
) {
1964 JS::Rooted
<JSObject
*> obj(aCx
, JS_NewPlainObject(aCx
));
1966 JS::Rooted
<JS::Value
> screenWidth(aCx
,
1967 JS::Int32Value(displayInfo
.mScreenWidth
));
1968 JS_SetProperty(aCx
, obj
, "screenWidth", screenWidth
);
1970 JS::Rooted
<JS::Value
> screenHeight(
1971 aCx
, JS::Int32Value(displayInfo
.mScreenHeight
));
1972 JS_SetProperty(aCx
, obj
, "screenHeight", screenHeight
);
1974 JS::Rooted
<JS::Value
> refreshRate(aCx
,
1975 JS::Int32Value(displayInfo
.mRefreshRate
));
1976 JS_SetProperty(aCx
, obj
, "refreshRate", refreshRate
);
1978 JS::Rooted
<JS::Value
> pseudoDisplay(
1979 aCx
, JS::BooleanValue(displayInfo
.mIsPseudoDisplay
));
1980 JS_SetProperty(aCx
, obj
, "pseudoDisplay", pseudoDisplay
);
1982 JS::Rooted
<JS::Value
> element(aCx
, JS::ObjectValue(*obj
));
1983 JS_SetElement(aCx
, aOutArray
, deviceCount
++, element
);
1988 void GfxInfo::DescribeFeatures(JSContext
* aCx
, JS::Handle
<JSObject
*> aObj
) {
1989 // Add the platform neutral features
1990 GfxInfoBase::DescribeFeatures(aCx
, aObj
);
1992 JS::Rooted
<JSObject
*> obj(aCx
);
1994 gfx::FeatureState
& d3d11
= gfxConfig::GetFeature(Feature::D3D11_COMPOSITING
);
1995 if (!InitFeatureObject(aCx
, aObj
, "d3d11", d3d11
, &obj
)) {
1998 if (d3d11
.GetValue() == gfx::FeatureStatus::Available
) {
1999 DeviceManagerDx
* dm
= DeviceManagerDx::Get();
2000 JS::Rooted
<JS::Value
> val(aCx
,
2001 JS::Int32Value(dm
->GetCompositorFeatureLevel()));
2002 JS_SetProperty(aCx
, obj
, "version", val
);
2004 val
= JS::BooleanValue(dm
->IsWARP());
2005 JS_SetProperty(aCx
, obj
, "warp", val
);
2007 val
= JS::BooleanValue(dm
->TextureSharingWorks());
2008 JS_SetProperty(aCx
, obj
, "textureSharing", val
);
2010 bool blocklisted
= false;
2011 if (nsCOMPtr
<nsIGfxInfo
> gfxInfo
= components::GfxInfo::Service()) {
2013 nsCString discardFailureId
;
2015 gfxInfo
->GetFeatureStatus(nsIGfxInfo::FEATURE_DIRECT3D_11_LAYERS
,
2016 discardFailureId
, &status
))) {
2017 blocklisted
= (status
!= nsIGfxInfo::FEATURE_STATUS_OK
);
2021 val
= JS::BooleanValue(blocklisted
);
2022 JS_SetProperty(aCx
, obj
, "blocklisted", val
);
2025 gfx::FeatureState
& d2d
= gfxConfig::GetFeature(Feature::DIRECT2D
);
2026 if (!InitFeatureObject(aCx
, aObj
, "d2d", d2d
, &obj
)) {
2030 const char* version
= "1.1";
2031 JS::Rooted
<JSString
*> str(aCx
, JS_NewStringCopyZ(aCx
, version
));
2032 JS::Rooted
<JS::Value
> val(aCx
, JS::StringValue(str
));
2033 JS_SetProperty(aCx
, obj
, "version", val
);
2039 // Implement nsIGfxInfoDebug
2041 NS_IMETHODIMP
GfxInfo::SpoofVendorID(const nsAString
& aVendorID
) {
2042 mAdapterVendorID
[mActiveGPUIndex
] = aVendorID
;
2046 NS_IMETHODIMP
GfxInfo::SpoofDeviceID(const nsAString
& aDeviceID
) {
2047 mAdapterDeviceID
[mActiveGPUIndex
] = aDeviceID
;
2051 NS_IMETHODIMP
GfxInfo::SpoofDriverVersion(const nsAString
& aDriverVersion
) {
2052 mDriverVersion
[mActiveGPUIndex
] = aDriverVersion
;
2056 NS_IMETHODIMP
GfxInfo::SpoofOSVersion(uint32_t aVersion
) {
2057 mWindowsVersion
= aVersion
;
2061 NS_IMETHODIMP
GfxInfo::FireTestProcess() { return NS_OK
; }