1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/widget/windows/GfxInfo.cpp Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,1108 @@ 1.4 +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 1.5 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.6 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.7 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.8 + 1.9 +#include "mozilla/ArrayUtils.h" 1.10 + 1.11 +#include <windows.h> 1.12 +#include <setupapi.h> 1.13 +#include "gfxWindowsPlatform.h" 1.14 +#include "GfxInfo.h" 1.15 +#include "GfxInfoWebGL.h" 1.16 +#include "nsUnicharUtils.h" 1.17 +#include "prenv.h" 1.18 +#include "prprf.h" 1.19 +#include "GfxDriverInfo.h" 1.20 +#include "mozilla/Preferences.h" 1.21 +#include "nsPrintfCString.h" 1.22 + 1.23 +#if defined(MOZ_CRASHREPORTER) 1.24 +#include "nsExceptionHandler.h" 1.25 +#include "nsICrashReporter.h" 1.26 +#define NS_CRASHREPORTER_CONTRACTID "@mozilla.org/toolkit/crash-reporter;1" 1.27 +#endif 1.28 + 1.29 +using namespace mozilla; 1.30 +using namespace mozilla::widget; 1.31 + 1.32 +#ifdef DEBUG 1.33 +NS_IMPL_ISUPPORTS_INHERITED(GfxInfo, GfxInfoBase, nsIGfxInfoDebug) 1.34 +#endif 1.35 + 1.36 +static const uint32_t allWindowsVersions = 0xffffffff; 1.37 + 1.38 +GfxInfo::GfxInfo() 1.39 + : mWindowsVersion(0), 1.40 + mHasDualGPU(false), 1.41 + mIsGPU2Active(false) 1.42 +{ 1.43 +} 1.44 + 1.45 +/* GetD2DEnabled and GetDwriteEnabled shouldn't be called until after gfxPlatform initialization 1.46 + * has occurred because they depend on it for information. (See bug 591561) */ 1.47 +nsresult 1.48 +GfxInfo::GetD2DEnabled(bool *aEnabled) 1.49 +{ 1.50 + *aEnabled = gfxWindowsPlatform::GetPlatform()->GetRenderMode() == gfxWindowsPlatform::RENDER_DIRECT2D; 1.51 + return NS_OK; 1.52 +} 1.53 + 1.54 +nsresult 1.55 +GfxInfo::GetDWriteEnabled(bool *aEnabled) 1.56 +{ 1.57 + *aEnabled = gfxWindowsPlatform::GetPlatform()->DWriteEnabled(); 1.58 + return NS_OK; 1.59 +} 1.60 + 1.61 +/* readonly attribute DOMString DWriteVersion; */ 1.62 +NS_IMETHODIMP 1.63 +GfxInfo::GetDWriteVersion(nsAString & aDwriteVersion) 1.64 +{ 1.65 + gfxWindowsPlatform::GetDLLVersion(L"dwrite.dll", aDwriteVersion); 1.66 + return NS_OK; 1.67 +} 1.68 + 1.69 +#define PIXEL_STRUCT_RGB 1 1.70 +#define PIXEL_STRUCT_BGR 2 1.71 + 1.72 +/* readonly attribute DOMString cleartypeParameters; */ 1.73 +NS_IMETHODIMP 1.74 +GfxInfo::GetCleartypeParameters(nsAString & aCleartypeParams) 1.75 +{ 1.76 + nsTArray<ClearTypeParameterInfo> clearTypeParams; 1.77 + 1.78 + gfxWindowsPlatform::GetPlatform()->GetCleartypeParams(clearTypeParams); 1.79 + uint32_t d, numDisplays = clearTypeParams.Length(); 1.80 + bool displayNames = (numDisplays > 1); 1.81 + bool foundData = false; 1.82 + nsString outStr; 1.83 + 1.84 + for (d = 0; d < numDisplays; d++) { 1.85 + ClearTypeParameterInfo& params = clearTypeParams[d]; 1.86 + 1.87 + if (displayNames) { 1.88 + outStr.AppendPrintf("%s [ ", params.displayName.get()); 1.89 + } 1.90 + 1.91 + if (params.gamma >= 0) { 1.92 + foundData = true; 1.93 + outStr.AppendPrintf("Gamma: %d ", params.gamma); 1.94 + } 1.95 + 1.96 + if (params.pixelStructure >= 0) { 1.97 + foundData = true; 1.98 + if (params.pixelStructure == PIXEL_STRUCT_RGB || 1.99 + params.pixelStructure == PIXEL_STRUCT_BGR) 1.100 + { 1.101 + outStr.AppendPrintf("Pixel Structure: %s ", 1.102 + (params.pixelStructure == PIXEL_STRUCT_RGB ? 1.103 + L"RGB" : L"BGR")); 1.104 + } else { 1.105 + outStr.AppendPrintf("Pixel Structure: %d ", params.pixelStructure); 1.106 + } 1.107 + } 1.108 + 1.109 + if (params.clearTypeLevel >= 0) { 1.110 + foundData = true; 1.111 + outStr.AppendPrintf("ClearType Level: %d ", params.clearTypeLevel); 1.112 + } 1.113 + 1.114 + if (params.enhancedContrast >= 0) { 1.115 + foundData = true; 1.116 + outStr.AppendPrintf("Enhanced Contrast: %d ", params.enhancedContrast); 1.117 + } 1.118 + 1.119 + if (displayNames) { 1.120 + outStr.Append(MOZ_UTF16("] ")); 1.121 + } 1.122 + } 1.123 + 1.124 + if (foundData) { 1.125 + aCleartypeParams.Assign(outStr); 1.126 + return NS_OK; 1.127 + } 1.128 + return NS_ERROR_FAILURE; 1.129 +} 1.130 + 1.131 +static nsresult GetKeyValue(const WCHAR* keyLocation, const WCHAR* keyName, nsAString& destString, int type) 1.132 +{ 1.133 + HKEY key; 1.134 + DWORD dwcbData; 1.135 + DWORD dValue; 1.136 + DWORD resultType; 1.137 + LONG result; 1.138 + nsresult retval = NS_OK; 1.139 + 1.140 + result = RegOpenKeyExW(HKEY_LOCAL_MACHINE, keyLocation, 0, KEY_QUERY_VALUE, &key); 1.141 + if (result != ERROR_SUCCESS) { 1.142 + return NS_ERROR_FAILURE; 1.143 + } 1.144 + 1.145 + switch (type) { 1.146 + case REG_DWORD: { 1.147 + // We only use this for vram size 1.148 + dwcbData = sizeof(dValue); 1.149 + result = RegQueryValueExW(key, keyName, nullptr, &resultType, 1.150 + (LPBYTE)&dValue, &dwcbData); 1.151 + if (result == ERROR_SUCCESS && resultType == REG_DWORD) { 1.152 + dValue = dValue / 1024 / 1024; 1.153 + destString.AppendInt(int32_t(dValue)); 1.154 + } else { 1.155 + retval = NS_ERROR_FAILURE; 1.156 + } 1.157 + break; 1.158 + } 1.159 + case REG_MULTI_SZ: { 1.160 + // A chain of null-separated strings; we convert the nulls to spaces 1.161 + WCHAR wCharValue[1024]; 1.162 + dwcbData = sizeof(wCharValue); 1.163 + 1.164 + result = RegQueryValueExW(key, keyName, nullptr, &resultType, 1.165 + (LPBYTE)wCharValue, &dwcbData); 1.166 + if (result == ERROR_SUCCESS && resultType == REG_MULTI_SZ) { 1.167 + // This bit here could probably be cleaner. 1.168 + bool isValid = false; 1.169 + 1.170 + DWORD strLen = dwcbData/sizeof(wCharValue[0]); 1.171 + for (DWORD i = 0; i < strLen; i++) { 1.172 + if (wCharValue[i] == '\0') { 1.173 + if (i < strLen - 1 && wCharValue[i + 1] == '\0') { 1.174 + isValid = true; 1.175 + break; 1.176 + } else { 1.177 + wCharValue[i] = ' '; 1.178 + } 1.179 + } 1.180 + } 1.181 + 1.182 + // ensure wCharValue is null terminated 1.183 + wCharValue[strLen-1] = '\0'; 1.184 + 1.185 + if (isValid) 1.186 + destString = wCharValue; 1.187 + 1.188 + } else { 1.189 + retval = NS_ERROR_FAILURE; 1.190 + } 1.191 + 1.192 + break; 1.193 + } 1.194 + } 1.195 + RegCloseKey(key); 1.196 + 1.197 + return retval; 1.198 +} 1.199 + 1.200 +// The driver ID is a string like PCI\VEN_15AD&DEV_0405&SUBSYS_040515AD, possibly 1.201 +// followed by &REV_XXXX. We uppercase the string, and strip the &REV_ part 1.202 +// from it, if found. 1.203 +static void normalizeDriverId(nsString& driverid) { 1.204 + ToUpperCase(driverid); 1.205 + int32_t rev = driverid.Find(NS_LITERAL_CSTRING("&REV_")); 1.206 + if (rev != -1) { 1.207 + driverid.Cut(rev, driverid.Length()); 1.208 + } 1.209 +} 1.210 + 1.211 +// The device ID is a string like PCI\VEN_15AD&DEV_0405&SUBSYS_040515AD 1.212 +// this function is used to extract the id's out of it 1.213 +uint32_t 1.214 +ParseIDFromDeviceID(const nsAString &key, const char *prefix, int length) 1.215 +{ 1.216 + nsAutoString id(key); 1.217 + ToUpperCase(id); 1.218 + int32_t start = id.Find(prefix); 1.219 + if (start != -1) { 1.220 + id.Cut(0, start + strlen(prefix)); 1.221 + id.Truncate(length); 1.222 + } 1.223 + nsresult err; 1.224 + return id.ToInteger(&err, 16); 1.225 +} 1.226 + 1.227 +// OS version in 16.16 major/minor form 1.228 +// based on http://msdn.microsoft.com/en-us/library/ms724834(VS.85).aspx 1.229 +enum { 1.230 + kWindowsUnknown = 0, 1.231 + kWindowsXP = 0x50001, 1.232 + kWindowsServer2003 = 0x50002, 1.233 + kWindowsVista = 0x60000, 1.234 + kWindows7 = 0x60001, 1.235 + kWindows8 = 0x60002, 1.236 + kWindows8_1 = 0x60003 1.237 +}; 1.238 + 1.239 +static int32_t 1.240 +WindowsOSVersion() 1.241 +{ 1.242 + static int32_t winVersion = UNINITIALIZED_VALUE; 1.243 + 1.244 + OSVERSIONINFO vinfo; 1.245 + 1.246 + if (winVersion == UNINITIALIZED_VALUE) { 1.247 + vinfo.dwOSVersionInfoSize = sizeof (vinfo); 1.248 +#pragma warning(push) 1.249 +#pragma warning(disable:4996) 1.250 + if (!GetVersionEx(&vinfo)) { 1.251 +#pragma warning(pop) 1.252 + winVersion = kWindowsUnknown; 1.253 + } else { 1.254 + winVersion = int32_t(vinfo.dwMajorVersion << 16) + vinfo.dwMinorVersion; 1.255 + } 1.256 + } 1.257 + 1.258 + return winVersion; 1.259 +} 1.260 + 1.261 +/* Other interesting places for info: 1.262 + * IDXGIAdapter::GetDesc() 1.263 + * IDirectDraw7::GetAvailableVidMem() 1.264 + * e->GetAvailableTextureMem() 1.265 + * */ 1.266 + 1.267 +#define DEVICE_KEY_PREFIX L"\\Registry\\Machine\\" 1.268 +nsresult 1.269 +GfxInfo::Init() 1.270 +{ 1.271 + nsresult rv = GfxInfoBase::Init(); 1.272 + 1.273 + DISPLAY_DEVICEW displayDevice; 1.274 + displayDevice.cb = sizeof(displayDevice); 1.275 + int deviceIndex = 0; 1.276 + 1.277 + const char *spoofedWindowsVersion = PR_GetEnv("MOZ_GFX_SPOOF_WINDOWS_VERSION"); 1.278 + if (spoofedWindowsVersion) { 1.279 + PR_sscanf(spoofedWindowsVersion, "%x", &mWindowsVersion); 1.280 + } else { 1.281 + mWindowsVersion = WindowsOSVersion(); 1.282 + } 1.283 + 1.284 + mDeviceKeyDebug = NS_LITERAL_STRING("PrimarySearch"); 1.285 + 1.286 + while (EnumDisplayDevicesW(nullptr, deviceIndex, &displayDevice, 0)) { 1.287 + if (displayDevice.StateFlags & DISPLAY_DEVICE_PRIMARY_DEVICE) { 1.288 + mDeviceKeyDebug = NS_LITERAL_STRING("NullSearch"); 1.289 + break; 1.290 + } 1.291 + deviceIndex++; 1.292 + } 1.293 + 1.294 + // make sure the string is nullptr terminated 1.295 + if (wcsnlen(displayDevice.DeviceKey, ArrayLength(displayDevice.DeviceKey)) 1.296 + == ArrayLength(displayDevice.DeviceKey)) { 1.297 + // we did not find a nullptr 1.298 + return rv; 1.299 + } 1.300 + 1.301 + mDeviceKeyDebug = displayDevice.DeviceKey; 1.302 + 1.303 + /* DeviceKey is "reserved" according to MSDN so we'll be careful with it */ 1.304 + /* check that DeviceKey begins with DEVICE_KEY_PREFIX */ 1.305 + /* some systems have a DeviceKey starting with \REGISTRY\Machine\ so we need to compare case insenstively */ 1.306 + if (_wcsnicmp(displayDevice.DeviceKey, DEVICE_KEY_PREFIX, ArrayLength(DEVICE_KEY_PREFIX)-1) != 0) 1.307 + return rv; 1.308 + 1.309 + // chop off DEVICE_KEY_PREFIX 1.310 + mDeviceKey = displayDevice.DeviceKey + ArrayLength(DEVICE_KEY_PREFIX)-1; 1.311 + 1.312 + mDeviceID = displayDevice.DeviceID; 1.313 + mDeviceString = displayDevice.DeviceString; 1.314 + 1.315 + // On Windows 8 and Server 2012 hosts, we want to not block RDP 1.316 + // sessions from attempting hardware acceleration. RemoteFX 1.317 + // provides features and functionaltiy that can give a good D3D10 + 1.318 + // D2D + DirectWrite experience emulated via a software GPU. 1.319 + // 1.320 + // Unfortunately, the Device ID is nullptr, and we can't enumerate 1.321 + // it using the setup infrastructure (SetupDiGetClassDevsW below 1.322 + // will return INVALID_HANDLE_VALUE). 1.323 + if (mWindowsVersion == kWindows8 && 1.324 + mDeviceID.Length() == 0 && 1.325 + mDeviceString.EqualsLiteral("RDPUDD Chained DD")) 1.326 + { 1.327 + WCHAR sysdir[255]; 1.328 + UINT len = GetSystemDirectory(sysdir, sizeof(sysdir)); 1.329 + if (len < sizeof(sysdir)) { 1.330 + nsString rdpudd(sysdir); 1.331 + rdpudd.AppendLiteral("\\rdpudd.dll"); 1.332 + gfxWindowsPlatform::GetDLLVersion(rdpudd.BeginReading(), mDriverVersion); 1.333 + mDriverDate.AssignLiteral("01-01-1970"); 1.334 + 1.335 + // 0x1414 is Microsoft; 0xfefe is an invented (and unused) code 1.336 + mDeviceID.AssignLiteral("PCI\\VEN_1414&DEV_FEFE&SUBSYS_00000000"); 1.337 + } 1.338 + } 1.339 + 1.340 + /* create a device information set composed of the current display device */ 1.341 + HDEVINFO devinfo = SetupDiGetClassDevsW(nullptr, mDeviceID.get(), nullptr, 1.342 + DIGCF_PRESENT | DIGCF_PROFILE | DIGCF_ALLCLASSES); 1.343 + 1.344 + if (devinfo != INVALID_HANDLE_VALUE) { 1.345 + HKEY key; 1.346 + LONG result; 1.347 + WCHAR value[255]; 1.348 + DWORD dwcbData; 1.349 + SP_DEVINFO_DATA devinfoData; 1.350 + DWORD memberIndex = 0; 1.351 + 1.352 + devinfoData.cbSize = sizeof(devinfoData); 1.353 + NS_NAMED_LITERAL_STRING(driverKeyPre, "System\\CurrentControlSet\\Control\\Class\\"); 1.354 + /* enumerate device information elements in the device information set */ 1.355 + while (SetupDiEnumDeviceInfo(devinfo, memberIndex++, &devinfoData)) { 1.356 + /* get a string that identifies the device's driver key */ 1.357 + if (SetupDiGetDeviceRegistryPropertyW(devinfo, 1.358 + &devinfoData, 1.359 + SPDRP_DRIVER, 1.360 + nullptr, 1.361 + (PBYTE)value, 1.362 + sizeof(value), 1.363 + nullptr)) { 1.364 + nsAutoString driverKey(driverKeyPre); 1.365 + driverKey += value; 1.366 + result = RegOpenKeyExW(HKEY_LOCAL_MACHINE, driverKey.get(), 0, KEY_QUERY_VALUE, &key); 1.367 + if (result == ERROR_SUCCESS) { 1.368 + /* we've found the driver we're looking for */ 1.369 + dwcbData = sizeof(value); 1.370 + result = RegQueryValueExW(key, L"DriverVersion", nullptr, nullptr, 1.371 + (LPBYTE)value, &dwcbData); 1.372 + if (result == ERROR_SUCCESS) { 1.373 + mDriverVersion = value; 1.374 + } else { 1.375 + // If the entry wasn't found, assume the worst (0.0.0.0). 1.376 + mDriverVersion.AssignLiteral("0.0.0.0"); 1.377 + } 1.378 + dwcbData = sizeof(value); 1.379 + result = RegQueryValueExW(key, L"DriverDate", nullptr, nullptr, 1.380 + (LPBYTE)value, &dwcbData); 1.381 + if (result == ERROR_SUCCESS) { 1.382 + mDriverDate = value; 1.383 + } else { 1.384 + // Again, assume the worst 1.385 + mDriverDate.AssignLiteral("01-01-1970"); 1.386 + } 1.387 + RegCloseKey(key); 1.388 + break; 1.389 + } 1.390 + } 1.391 + } 1.392 + 1.393 + SetupDiDestroyDeviceInfoList(devinfo); 1.394 + } 1.395 + 1.396 + mAdapterVendorID.AppendPrintf("0x%04x", ParseIDFromDeviceID(mDeviceID, "VEN_", 4)); 1.397 + mAdapterDeviceID.AppendPrintf("0x%04x", ParseIDFromDeviceID(mDeviceID, "&DEV_", 4)); 1.398 + mAdapterSubsysID = ParseIDFromDeviceID(mDeviceID, "&SUBSYS_", 8); 1.399 + 1.400 + // We now check for second display adapter. 1.401 + 1.402 + // Device interface class for display adapters. 1.403 + CLSID GUID_DISPLAY_DEVICE_ARRIVAL; 1.404 + HRESULT hresult = CLSIDFromString(L"{1CA05180-A699-450A-9A0C-DE4FBE3DDD89}", 1.405 + &GUID_DISPLAY_DEVICE_ARRIVAL); 1.406 + if (hresult == NOERROR) { 1.407 + devinfo = SetupDiGetClassDevsW(&GUID_DISPLAY_DEVICE_ARRIVAL, 1.408 + nullptr, nullptr, 1.409 + DIGCF_PRESENT | DIGCF_INTERFACEDEVICE); 1.410 + 1.411 + if (devinfo != INVALID_HANDLE_VALUE) { 1.412 + HKEY key; 1.413 + LONG result; 1.414 + WCHAR value[255]; 1.415 + DWORD dwcbData; 1.416 + SP_DEVINFO_DATA devinfoData; 1.417 + DWORD memberIndex = 0; 1.418 + devinfoData.cbSize = sizeof(devinfoData); 1.419 + 1.420 + nsAutoString adapterDriver2; 1.421 + nsAutoString deviceID2; 1.422 + nsAutoString driverVersion2; 1.423 + nsAutoString driverDate2; 1.424 + uint32_t adapterVendorID2; 1.425 + uint32_t adapterDeviceID2; 1.426 + 1.427 + NS_NAMED_LITERAL_STRING(driverKeyPre, "System\\CurrentControlSet\\Control\\Class\\"); 1.428 + /* enumerate device information elements in the device information set */ 1.429 + while (SetupDiEnumDeviceInfo(devinfo, memberIndex++, &devinfoData)) { 1.430 + /* get a string that identifies the device's driver key */ 1.431 + if (SetupDiGetDeviceRegistryPropertyW(devinfo, 1.432 + &devinfoData, 1.433 + SPDRP_DRIVER, 1.434 + nullptr, 1.435 + (PBYTE)value, 1.436 + sizeof(value), 1.437 + nullptr)) { 1.438 + nsAutoString driverKey2(driverKeyPre); 1.439 + driverKey2 += value; 1.440 + result = RegOpenKeyExW(HKEY_LOCAL_MACHINE, driverKey2.get(), 0, KEY_QUERY_VALUE, &key); 1.441 + if (result == ERROR_SUCCESS) { 1.442 + dwcbData = sizeof(value); 1.443 + result = RegQueryValueExW(key, L"MatchingDeviceId", nullptr, 1.444 + nullptr, (LPBYTE)value, &dwcbData); 1.445 + if (result != ERROR_SUCCESS) { 1.446 + continue; 1.447 + } 1.448 + deviceID2 = value; 1.449 + nsAutoString adapterVendorID2String; 1.450 + nsAutoString adapterDeviceID2String; 1.451 + adapterVendorID2 = ParseIDFromDeviceID(deviceID2, "VEN_", 4); 1.452 + adapterVendorID2String.AppendPrintf("0x%04x", adapterVendorID2); 1.453 + adapterDeviceID2 = ParseIDFromDeviceID(deviceID2, "&DEV_", 4); 1.454 + adapterDeviceID2String.AppendPrintf("0x%04x", adapterDeviceID2); 1.455 + if (mAdapterVendorID == adapterVendorID2String && 1.456 + mAdapterDeviceID == adapterDeviceID2String) { 1.457 + RegCloseKey(key); 1.458 + continue; 1.459 + } 1.460 + 1.461 + // If this device is missing driver information, it is unlikely to 1.462 + // be a real display adapter. 1.463 + if (NS_FAILED(GetKeyValue(driverKey2.get(), L"InstalledDisplayDrivers", 1.464 + adapterDriver2, REG_MULTI_SZ))) { 1.465 + RegCloseKey(key); 1.466 + continue; 1.467 + } 1.468 + dwcbData = sizeof(value); 1.469 + result = RegQueryValueExW(key, L"DriverVersion", nullptr, nullptr, 1.470 + (LPBYTE)value, &dwcbData); 1.471 + if (result != ERROR_SUCCESS) { 1.472 + RegCloseKey(key); 1.473 + continue; 1.474 + } 1.475 + driverVersion2 = value; 1.476 + dwcbData = sizeof(value); 1.477 + result = RegQueryValueExW(key, L"DriverDate", nullptr, nullptr, 1.478 + (LPBYTE)value, &dwcbData); 1.479 + if (result != ERROR_SUCCESS) { 1.480 + RegCloseKey(key); 1.481 + continue; 1.482 + } 1.483 + driverDate2 = value; 1.484 + dwcbData = sizeof(value); 1.485 + result = RegQueryValueExW(key, L"Device Description", nullptr, 1.486 + nullptr, (LPBYTE)value, &dwcbData); 1.487 + if (result != ERROR_SUCCESS) { 1.488 + dwcbData = sizeof(value); 1.489 + result = RegQueryValueExW(key, L"DriverDesc", nullptr, nullptr, 1.490 + (LPBYTE)value, &dwcbData); 1.491 + } 1.492 + RegCloseKey(key); 1.493 + if (result == ERROR_SUCCESS) { 1.494 + mHasDualGPU = true; 1.495 + mDeviceString2 = value; 1.496 + mDeviceID2 = deviceID2; 1.497 + mDeviceKey2 = driverKey2; 1.498 + mDriverVersion2 = driverVersion2; 1.499 + mDriverDate2 = driverDate2; 1.500 + mAdapterVendorID2.AppendPrintf("0x%04x", adapterVendorID2); 1.501 + mAdapterDeviceID2.AppendPrintf("0x%04x", adapterDeviceID2); 1.502 + mAdapterSubsysID2 = ParseIDFromDeviceID(mDeviceID2, "&SUBSYS_", 8); 1.503 + break; 1.504 + } 1.505 + } 1.506 + } 1.507 + } 1.508 + 1.509 + SetupDiDestroyDeviceInfoList(devinfo); 1.510 + } 1.511 + } 1.512 + 1.513 + mHasDriverVersionMismatch = false; 1.514 + if (mAdapterVendorID == GfxDriverInfo::GetDeviceVendor(VendorIntel)) { 1.515 + // we've had big crashers (bugs 590373 and 595364) apparently correlated 1.516 + // with bad Intel driver installations where the DriverVersion reported 1.517 + // by the registry was not the version of the DLL. 1.518 + bool is64bitApp = sizeof(void*) == 8; 1.519 + const char16_t *dllFileName = is64bitApp 1.520 + ? MOZ_UTF16("igd10umd64.dll") 1.521 + : MOZ_UTF16("igd10umd32.dll"), 1.522 + *dllFileName2 = is64bitApp 1.523 + ? MOZ_UTF16("igd10iumd64.dll") 1.524 + : MOZ_UTF16("igd10iumd32.dll"); 1.525 + nsString dllVersion, dllVersion2; 1.526 + gfxWindowsPlatform::GetDLLVersion((char16_t*)dllFileName, dllVersion); 1.527 + gfxWindowsPlatform::GetDLLVersion((char16_t*)dllFileName2, dllVersion2); 1.528 + 1.529 + uint64_t dllNumericVersion = 0, dllNumericVersion2 = 0, 1.530 + driverNumericVersion = 0, knownSafeMismatchVersion = 0; 1.531 + ParseDriverVersion(dllVersion, &dllNumericVersion); 1.532 + ParseDriverVersion(dllVersion2, &dllNumericVersion2); 1.533 + ParseDriverVersion(mDriverVersion, &driverNumericVersion); 1.534 + ParseDriverVersion(NS_LITERAL_STRING("9.17.10.0"), &knownSafeMismatchVersion); 1.535 + 1.536 + // If there's a driver version mismatch, consider this harmful only when 1.537 + // the driver version is less than knownSafeMismatchVersion. See the 1.538 + // above comment about crashes with old mismatches. If the GetDllVersion 1.539 + // call fails, then they return 0, so that will be considered a mismatch. 1.540 + if (dllNumericVersion != driverNumericVersion && 1.541 + dllNumericVersion2 != driverNumericVersion && 1.542 + (driverNumericVersion < knownSafeMismatchVersion || 1.543 + std::max(dllNumericVersion, dllNumericVersion2) < knownSafeMismatchVersion)) { 1.544 + mHasDriverVersionMismatch = true; 1.545 + } 1.546 + } 1.547 + 1.548 + const char *spoofedDriverVersionString = PR_GetEnv("MOZ_GFX_SPOOF_DRIVER_VERSION"); 1.549 + if (spoofedDriverVersionString) { 1.550 + mDriverVersion.AssignASCII(spoofedDriverVersionString); 1.551 + } 1.552 + 1.553 + const char *spoofedVendor = PR_GetEnv("MOZ_GFX_SPOOF_VENDOR_ID"); 1.554 + if (spoofedVendor) { 1.555 + mAdapterVendorID.AssignASCII(spoofedVendor); 1.556 + } 1.557 + 1.558 + const char *spoofedDevice = PR_GetEnv("MOZ_GFX_SPOOF_DEVICE_ID"); 1.559 + if (spoofedDevice) { 1.560 + mAdapterDeviceID.AssignASCII(spoofedDevice); 1.561 + } 1.562 + 1.563 + AddCrashReportAnnotations(); 1.564 + 1.565 + return rv; 1.566 +} 1.567 + 1.568 +/* readonly attribute DOMString adapterDescription; */ 1.569 +NS_IMETHODIMP 1.570 +GfxInfo::GetAdapterDescription(nsAString & aAdapterDescription) 1.571 +{ 1.572 + aAdapterDescription = mDeviceString; 1.573 + return NS_OK; 1.574 +} 1.575 + 1.576 +/* readonly attribute DOMString adapterDescription2; */ 1.577 +NS_IMETHODIMP 1.578 +GfxInfo::GetAdapterDescription2(nsAString & aAdapterDescription) 1.579 +{ 1.580 + aAdapterDescription = mDeviceString2; 1.581 + return NS_OK; 1.582 +} 1.583 + 1.584 +/* readonly attribute DOMString adapterRAM; */ 1.585 +NS_IMETHODIMP 1.586 +GfxInfo::GetAdapterRAM(nsAString & aAdapterRAM) 1.587 +{ 1.588 + if (NS_FAILED(GetKeyValue(mDeviceKey.get(), L"HardwareInformation.MemorySize", aAdapterRAM, REG_DWORD))) 1.589 + aAdapterRAM = L"Unknown"; 1.590 + return NS_OK; 1.591 +} 1.592 + 1.593 +/* readonly attribute DOMString adapterRAM2; */ 1.594 +NS_IMETHODIMP 1.595 +GfxInfo::GetAdapterRAM2(nsAString & aAdapterRAM) 1.596 +{ 1.597 + if (!mHasDualGPU) { 1.598 + aAdapterRAM.AssignLiteral(""); 1.599 + } else if (NS_FAILED(GetKeyValue(mDeviceKey2.get(), L"HardwareInformation.MemorySize", aAdapterRAM, REG_DWORD))) { 1.600 + aAdapterRAM = L"Unknown"; 1.601 + } 1.602 + return NS_OK; 1.603 +} 1.604 + 1.605 +/* readonly attribute DOMString adapterDriver; */ 1.606 +NS_IMETHODIMP 1.607 +GfxInfo::GetAdapterDriver(nsAString & aAdapterDriver) 1.608 +{ 1.609 + if (NS_FAILED(GetKeyValue(mDeviceKey.get(), L"InstalledDisplayDrivers", aAdapterDriver, REG_MULTI_SZ))) 1.610 + aAdapterDriver = L"Unknown"; 1.611 + return NS_OK; 1.612 +} 1.613 + 1.614 +/* readonly attribute DOMString adapterDriver2; */ 1.615 +NS_IMETHODIMP 1.616 +GfxInfo::GetAdapterDriver2(nsAString & aAdapterDriver) 1.617 +{ 1.618 + if (!mHasDualGPU) { 1.619 + aAdapterDriver.AssignLiteral(""); 1.620 + } else if (NS_FAILED(GetKeyValue(mDeviceKey2.get(), L"InstalledDisplayDrivers", aAdapterDriver, REG_MULTI_SZ))) { 1.621 + aAdapterDriver = L"Unknown"; 1.622 + } 1.623 + return NS_OK; 1.624 +} 1.625 + 1.626 +/* readonly attribute DOMString adapterDriverVersion; */ 1.627 +NS_IMETHODIMP 1.628 +GfxInfo::GetAdapterDriverVersion(nsAString & aAdapterDriverVersion) 1.629 +{ 1.630 + aAdapterDriverVersion = mDriverVersion; 1.631 + return NS_OK; 1.632 +} 1.633 + 1.634 +/* readonly attribute DOMString adapterDriverDate; */ 1.635 +NS_IMETHODIMP 1.636 +GfxInfo::GetAdapterDriverDate(nsAString & aAdapterDriverDate) 1.637 +{ 1.638 + aAdapterDriverDate = mDriverDate; 1.639 + return NS_OK; 1.640 +} 1.641 + 1.642 +/* readonly attribute DOMString adapterDriverVersion2; */ 1.643 +NS_IMETHODIMP 1.644 +GfxInfo::GetAdapterDriverVersion2(nsAString & aAdapterDriverVersion) 1.645 +{ 1.646 + aAdapterDriverVersion = mDriverVersion2; 1.647 + return NS_OK; 1.648 +} 1.649 + 1.650 +/* readonly attribute DOMString adapterDriverDate2; */ 1.651 +NS_IMETHODIMP 1.652 +GfxInfo::GetAdapterDriverDate2(nsAString & aAdapterDriverDate) 1.653 +{ 1.654 + aAdapterDriverDate = mDriverDate2; 1.655 + return NS_OK; 1.656 +} 1.657 + 1.658 +/* readonly attribute DOMString adapterVendorID; */ 1.659 +NS_IMETHODIMP 1.660 +GfxInfo::GetAdapterVendorID(nsAString & aAdapterVendorID) 1.661 +{ 1.662 + aAdapterVendorID = mAdapterVendorID; 1.663 + return NS_OK; 1.664 +} 1.665 + 1.666 +/* readonly attribute DOMString adapterVendorID2; */ 1.667 +NS_IMETHODIMP 1.668 +GfxInfo::GetAdapterVendorID2(nsAString & aAdapterVendorID) 1.669 +{ 1.670 + aAdapterVendorID = mAdapterVendorID2; 1.671 + return NS_OK; 1.672 +} 1.673 + 1.674 +/* readonly attribute DOMString adapterDeviceID; */ 1.675 +NS_IMETHODIMP 1.676 +GfxInfo::GetAdapterDeviceID(nsAString & aAdapterDeviceID) 1.677 +{ 1.678 + aAdapterDeviceID = mAdapterDeviceID; 1.679 + return NS_OK; 1.680 +} 1.681 + 1.682 +/* readonly attribute DOMString adapterDeviceID2; */ 1.683 +NS_IMETHODIMP 1.684 +GfxInfo::GetAdapterDeviceID2(nsAString & aAdapterDeviceID) 1.685 +{ 1.686 + aAdapterDeviceID = mAdapterDeviceID2; 1.687 + return NS_OK; 1.688 +} 1.689 + 1.690 +/* readonly attribute boolean isGPU2Active; */ 1.691 +NS_IMETHODIMP 1.692 +GfxInfo::GetIsGPU2Active(bool* aIsGPU2Active) 1.693 +{ 1.694 + *aIsGPU2Active = mIsGPU2Active; 1.695 + return NS_OK; 1.696 +} 1.697 + 1.698 +#if defined(MOZ_CRASHREPORTER) 1.699 +/* Cisco's VPN software can cause corruption of the floating point state. 1.700 + * Make a note of this in our crash reports so that some weird crashes 1.701 + * make more sense */ 1.702 +static void 1.703 +CheckForCiscoVPN() { 1.704 + LONG result; 1.705 + HKEY key; 1.706 + /* This will give false positives, but hopefully no false negatives */ 1.707 + result = RegOpenKeyExW(HKEY_LOCAL_MACHINE, L"Software\\Cisco Systems\\VPN Client", 0, KEY_QUERY_VALUE, &key); 1.708 + if (result == ERROR_SUCCESS) { 1.709 + RegCloseKey(key); 1.710 + CrashReporter::AppendAppNotesToCrashReport(NS_LITERAL_CSTRING("Cisco VPN\n")); 1.711 + } 1.712 +} 1.713 +#endif 1.714 + 1.715 +void 1.716 +GfxInfo::AddCrashReportAnnotations() 1.717 +{ 1.718 +#if defined(MOZ_CRASHREPORTER) 1.719 + CheckForCiscoVPN(); 1.720 + 1.721 + nsString deviceID, vendorID; 1.722 + nsCString narrowDeviceID, narrowVendorID; 1.723 + nsAutoString adapterDriverVersionString; 1.724 + 1.725 + GetAdapterDeviceID(deviceID); 1.726 + CopyUTF16toUTF8(deviceID, narrowDeviceID); 1.727 + GetAdapterVendorID(vendorID); 1.728 + CopyUTF16toUTF8(vendorID, narrowVendorID); 1.729 + GetAdapterDriverVersion(adapterDriverVersionString); 1.730 + 1.731 + CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("AdapterVendorID"), 1.732 + narrowVendorID); 1.733 + CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("AdapterDeviceID"), 1.734 + narrowDeviceID); 1.735 + 1.736 + /* Add an App Note for now so that we get the data immediately. These 1.737 + * can go away after we store the above in the socorro db */ 1.738 + nsAutoCString note; 1.739 + /* AppendPrintf only supports 32 character strings, mrghh. */ 1.740 + note.Append("AdapterVendorID: "); 1.741 + note.Append(narrowVendorID); 1.742 + note.Append(", AdapterDeviceID: "); 1.743 + note.Append(narrowDeviceID); 1.744 + note.AppendPrintf(", AdapterSubsysID: %08x, ", mAdapterSubsysID); 1.745 + note.Append("AdapterDriverVersion: "); 1.746 + note.Append(NS_LossyConvertUTF16toASCII(adapterDriverVersionString)); 1.747 + 1.748 + if (vendorID == GfxDriverInfo::GetDeviceVendor(VendorAll)) { 1.749 + /* if we didn't find a valid vendorID lets append the mDeviceID string to try to find out why */ 1.750 + note.Append(", "); 1.751 + LossyAppendUTF16toASCII(mDeviceID, note); 1.752 + note.Append(", "); 1.753 + LossyAppendUTF16toASCII(mDeviceKeyDebug, note); 1.754 + LossyAppendUTF16toASCII(mDeviceKeyDebug, note); 1.755 + } 1.756 + note.Append("\n"); 1.757 + 1.758 + if (mHasDualGPU) { 1.759 + nsString deviceID2, vendorID2; 1.760 + nsAutoString adapterDriverVersionString2; 1.761 + nsCString narrowDeviceID2, narrowVendorID2; 1.762 + 1.763 + note.AppendLiteral("Has dual GPUs. GPU #2: "); 1.764 + GetAdapterDeviceID2(deviceID2); 1.765 + CopyUTF16toUTF8(deviceID2, narrowDeviceID2); 1.766 + GetAdapterVendorID2(vendorID2); 1.767 + CopyUTF16toUTF8(vendorID2, narrowVendorID2); 1.768 + GetAdapterDriverVersion2(adapterDriverVersionString2); 1.769 + note.Append("AdapterVendorID2: "); 1.770 + note.Append(narrowVendorID2); 1.771 + note.Append(", AdapterDeviceID2: "); 1.772 + note.Append(narrowDeviceID2); 1.773 + note.AppendPrintf(", AdapterSubsysID2: %08x, ", mAdapterSubsysID2); 1.774 + note.AppendPrintf("AdapterDriverVersion2: "); 1.775 + note.Append(NS_LossyConvertUTF16toASCII(adapterDriverVersionString2)); 1.776 + } 1.777 + CrashReporter::AppendAppNotesToCrashReport(note); 1.778 + 1.779 +#endif 1.780 +} 1.781 + 1.782 +static OperatingSystem 1.783 +WindowsVersionToOperatingSystem(int32_t aWindowsVersion) 1.784 +{ 1.785 + switch(aWindowsVersion) { 1.786 + case kWindowsXP: 1.787 + return DRIVER_OS_WINDOWS_XP; 1.788 + case kWindowsServer2003: 1.789 + return DRIVER_OS_WINDOWS_SERVER_2003; 1.790 + case kWindowsVista: 1.791 + return DRIVER_OS_WINDOWS_VISTA; 1.792 + case kWindows7: 1.793 + return DRIVER_OS_WINDOWS_7; 1.794 + case kWindows8: 1.795 + return DRIVER_OS_WINDOWS_8; 1.796 + case kWindows8_1: 1.797 + return DRIVER_OS_WINDOWS_8_1; 1.798 + case kWindowsUnknown: 1.799 + default: 1.800 + return DRIVER_OS_UNKNOWN; 1.801 + }; 1.802 +} 1.803 + 1.804 +const nsTArray<GfxDriverInfo>& 1.805 +GfxInfo::GetGfxDriverInfo() 1.806 +{ 1.807 + if (!mDriverInfo->Length()) { 1.808 + /* 1.809 + * It should be noted here that more specialized rules on certain features 1.810 + * should be inserted -before- more generalized restriction. As the first 1.811 + * match for feature/OS/device found in the list will be used for the final 1.812 + * blacklisting call. 1.813 + */ 1.814 + 1.815 + /* 1.816 + * NVIDIA entries 1.817 + */ 1.818 + APPEND_TO_DRIVER_BLOCKLIST( DRIVER_OS_WINDOWS_VISTA, 1.819 + (nsAString&) GfxDriverInfo::GetDeviceVendor(VendorNVIDIA), GfxDriverInfo::allDevices, 1.820 + nsIGfxInfo::FEATURE_DIRECT2D, nsIGfxInfo::FEATURE_BLOCKED_DRIVER_VERSION, 1.821 + DRIVER_LESS_THAN, V(8,17,12,5721), "257.21" ); 1.822 + APPEND_TO_DRIVER_BLOCKLIST( DRIVER_OS_WINDOWS_7, 1.823 + (nsAString&) GfxDriverInfo::GetDeviceVendor(VendorNVIDIA), GfxDriverInfo::allDevices, 1.824 + nsIGfxInfo::FEATURE_DIRECT2D, nsIGfxInfo::FEATURE_BLOCKED_DRIVER_VERSION, 1.825 + DRIVER_LESS_THAN, V(8,17,12,5721), "257.21" ); 1.826 + APPEND_TO_DRIVER_BLOCKLIST( DRIVER_OS_WINDOWS_XP, 1.827 + (nsAString&) GfxDriverInfo::GetDeviceVendor(VendorNVIDIA), GfxDriverInfo::allDevices, 1.828 + GfxDriverInfo::allFeatures, nsIGfxInfo::FEATURE_BLOCKED_DRIVER_VERSION, 1.829 + DRIVER_LESS_THAN, V(6,14,11,8265), "182.65" ); 1.830 + APPEND_TO_DRIVER_BLOCKLIST( DRIVER_OS_WINDOWS_VISTA, 1.831 + (nsAString&) GfxDriverInfo::GetDeviceVendor(VendorNVIDIA), GfxDriverInfo::allDevices, 1.832 + GfxDriverInfo::allFeatures, nsIGfxInfo::FEATURE_BLOCKED_DRIVER_VERSION, 1.833 + DRIVER_LESS_THAN, V(8,17,11,8265), "182.65" ); 1.834 + APPEND_TO_DRIVER_BLOCKLIST( DRIVER_OS_WINDOWS_7, 1.835 + (nsAString&) GfxDriverInfo::GetDeviceVendor(VendorNVIDIA), GfxDriverInfo::allDevices, 1.836 + GfxDriverInfo::allFeatures, nsIGfxInfo::FEATURE_BLOCKED_DRIVER_VERSION, 1.837 + DRIVER_LESS_THAN, V(8,17,11,8265), "182.65" ); 1.838 + 1.839 + /* 1.840 + * AMD/ATI entries 1.841 + */ 1.842 + APPEND_TO_DRIVER_BLOCKLIST( DRIVER_OS_ALL, 1.843 + (nsAString&) GfxDriverInfo::GetDeviceVendor(VendorATI), GfxDriverInfo::allDevices, 1.844 + nsIGfxInfo::FEATURE_DIRECT2D, nsIGfxInfo::FEATURE_BLOCKED_DRIVER_VERSION, 1.845 + DRIVER_LESS_THAN, V(8,741,0,0), "10.6" ); 1.846 + APPEND_TO_DRIVER_BLOCKLIST( DRIVER_OS_ALL, 1.847 + (nsAString&) GfxDriverInfo::GetDeviceVendor(VendorAMD), GfxDriverInfo::allDevices, 1.848 + nsIGfxInfo::FEATURE_DIRECT2D, nsIGfxInfo::FEATURE_BLOCKED_DRIVER_VERSION, 1.849 + DRIVER_LESS_THAN, V(8,741,0,0), "10.6" ); 1.850 + APPEND_TO_DRIVER_BLOCKLIST( DRIVER_OS_ALL, 1.851 + (nsAString&) GfxDriverInfo::GetDeviceVendor(VendorATI), GfxDriverInfo::allDevices, 1.852 + GfxDriverInfo::allFeatures, nsIGfxInfo::FEATURE_BLOCKED_DRIVER_VERSION, 1.853 + DRIVER_LESS_THAN, V(8,62,0,0), "9.6" ); 1.854 + APPEND_TO_DRIVER_BLOCKLIST( DRIVER_OS_ALL, 1.855 + (nsAString&) GfxDriverInfo::GetDeviceVendor(VendorAMD), GfxDriverInfo::allDevices, 1.856 + GfxDriverInfo::allFeatures, nsIGfxInfo::FEATURE_BLOCKED_DRIVER_VERSION, 1.857 + DRIVER_LESS_THAN, V(8,62,0,0), "9.6" ); 1.858 + 1.859 + /* 1.860 + * Bug 783517 - crashes in AMD driver on Windows 8 1.861 + */ 1.862 + APPEND_TO_DRIVER_BLOCKLIST_RANGE( DRIVER_OS_WINDOWS_8, 1.863 + (nsAString&) GfxDriverInfo::GetDeviceVendor(VendorATI), GfxDriverInfo::allDevices, 1.864 + GfxDriverInfo::allFeatures, nsIGfxInfo::FEATURE_BLOCKED_DRIVER_VERSION, 1.865 + DRIVER_BETWEEN_INCLUSIVE_START, V(8,982,0,0), V(8,983,0,0), "!= 8.982.*.*" ); 1.866 + APPEND_TO_DRIVER_BLOCKLIST_RANGE( DRIVER_OS_WINDOWS_8, 1.867 + (nsAString&) GfxDriverInfo::GetDeviceVendor(VendorAMD), GfxDriverInfo::allDevices, 1.868 + GfxDriverInfo::allFeatures, nsIGfxInfo::FEATURE_BLOCKED_DRIVER_VERSION, 1.869 + DRIVER_BETWEEN_INCLUSIVE_START, V(8,982,0,0), V(8,983,0,0), "!= 8.982.*.*" ); 1.870 + 1.871 + /* OpenGL on any ATI/AMD hardware is discouraged 1.872 + * See: 1.873 + * bug 619773 - WebGL: Crash with blue screen : "NMI: Parity Check / Memory Parity Error" 1.874 + * bugs 584403, 584404, 620924 - crashes in atioglxx 1.875 + * + many complaints about incorrect rendering 1.876 + */ 1.877 + APPEND_TO_DRIVER_BLOCKLIST2( DRIVER_OS_ALL, 1.878 + (nsAString&) GfxDriverInfo::GetDeviceVendor(VendorATI), GfxDriverInfo::allDevices, 1.879 + nsIGfxInfo::FEATURE_OPENGL_LAYERS, nsIGfxInfo::FEATURE_DISCOURAGED, 1.880 + DRIVER_LESS_THAN, GfxDriverInfo::allDriverVersions ); 1.881 + APPEND_TO_DRIVER_BLOCKLIST2( DRIVER_OS_ALL, 1.882 + (nsAString&) GfxDriverInfo::GetDeviceVendor(VendorATI), GfxDriverInfo::allDevices, 1.883 + nsIGfxInfo::FEATURE_WEBGL_OPENGL, nsIGfxInfo::FEATURE_DISCOURAGED, 1.884 + DRIVER_LESS_THAN, GfxDriverInfo::allDriverVersions ); 1.885 + APPEND_TO_DRIVER_BLOCKLIST2( DRIVER_OS_ALL, 1.886 + (nsAString&) GfxDriverInfo::GetDeviceVendor(VendorAMD), GfxDriverInfo::allDevices, 1.887 + nsIGfxInfo::FEATURE_OPENGL_LAYERS, nsIGfxInfo::FEATURE_DISCOURAGED, 1.888 + DRIVER_LESS_THAN, GfxDriverInfo::allDriverVersions ); 1.889 + APPEND_TO_DRIVER_BLOCKLIST2( DRIVER_OS_ALL, 1.890 + (nsAString&) GfxDriverInfo::GetDeviceVendor(VendorAMD), GfxDriverInfo::allDevices, 1.891 + nsIGfxInfo::FEATURE_WEBGL_OPENGL, nsIGfxInfo::FEATURE_DISCOURAGED, 1.892 + DRIVER_LESS_THAN, GfxDriverInfo::allDriverVersions ); 1.893 + 1.894 + /* 1.895 + * Intel entries 1.896 + */ 1.897 + 1.898 + /* implement the blocklist from bug 594877 1.899 + * Block all features on any drivers before this, as there's a crash when a MS Hotfix is installed. 1.900 + * The crash itself is Direct2D-related, but for safety we block all features. 1.901 + */ 1.902 + #define IMPLEMENT_INTEL_DRIVER_BLOCKLIST(winVer, devFamily, driverVer) \ 1.903 + APPEND_TO_DRIVER_BLOCKLIST2( winVer, \ 1.904 + (nsAString&) GfxDriverInfo::GetDeviceVendor(VendorIntel), (GfxDeviceFamily*) GfxDriverInfo::GetDeviceFamily(devFamily), \ 1.905 + GfxDriverInfo::allFeatures, nsIGfxInfo::FEATURE_BLOCKED_DRIVER_VERSION, \ 1.906 + DRIVER_LESS_THAN, driverVer ) 1.907 + #define IMPLEMENT_INTEL_DRIVER_BLOCKLIST_D2D(winVer, devFamily, driverVer) \ 1.908 + APPEND_TO_DRIVER_BLOCKLIST2( winVer, \ 1.909 + (nsAString&) GfxDriverInfo::GetDeviceVendor(VendorIntel), (GfxDeviceFamily*) GfxDriverInfo::GetDeviceFamily(devFamily), \ 1.910 + nsIGfxInfo::FEATURE_DIRECT2D, nsIGfxInfo::FEATURE_BLOCKED_DRIVER_VERSION, \ 1.911 + DRIVER_LESS_THAN, driverVer ) 1.912 + 1.913 + IMPLEMENT_INTEL_DRIVER_BLOCKLIST_D2D(DRIVER_OS_WINDOWS_VISTA, IntelGMA500, V(7,14,10,1006)); 1.914 + IMPLEMENT_INTEL_DRIVER_BLOCKLIST_D2D(DRIVER_OS_WINDOWS_VISTA, IntelGMA900, GfxDriverInfo::allDriverVersions); 1.915 + IMPLEMENT_INTEL_DRIVER_BLOCKLIST_D2D(DRIVER_OS_WINDOWS_VISTA, IntelGMA950, V(7,14,10,1504)); 1.916 + IMPLEMENT_INTEL_DRIVER_BLOCKLIST_D2D(DRIVER_OS_WINDOWS_VISTA, IntelGMA3150, V(7,14,10,2124)); 1.917 + IMPLEMENT_INTEL_DRIVER_BLOCKLIST_D2D(DRIVER_OS_WINDOWS_VISTA, IntelGMAX3000, V(7,15,10,1666)); 1.918 + IMPLEMENT_INTEL_DRIVER_BLOCKLIST_D2D(DRIVER_OS_WINDOWS_VISTA, IntelGMAX4500HD, V(8,15,10,2202)); 1.919 + 1.920 + IMPLEMENT_INTEL_DRIVER_BLOCKLIST_D2D(DRIVER_OS_WINDOWS_7, IntelGMA500, V(5,0,0,2026)); 1.921 + IMPLEMENT_INTEL_DRIVER_BLOCKLIST_D2D(DRIVER_OS_WINDOWS_7, IntelGMA900, GfxDriverInfo::allDriverVersions); 1.922 + IMPLEMENT_INTEL_DRIVER_BLOCKLIST_D2D(DRIVER_OS_WINDOWS_7, IntelGMA950, V(8,15,10,1930)); 1.923 + IMPLEMENT_INTEL_DRIVER_BLOCKLIST_D2D(DRIVER_OS_WINDOWS_7, IntelGMA3150, V(8,14,10,2117)); 1.924 + IMPLEMENT_INTEL_DRIVER_BLOCKLIST_D2D(DRIVER_OS_WINDOWS_7, IntelGMAX3000, V(8,15,10,1930)); 1.925 + IMPLEMENT_INTEL_DRIVER_BLOCKLIST_D2D(DRIVER_OS_WINDOWS_7, IntelGMAX4500HD, V(8,15,10,2202)); 1.926 + 1.927 + IMPLEMENT_INTEL_DRIVER_BLOCKLIST(DRIVER_OS_WINDOWS_XP, IntelGMA500, V(3,0,20,3200)); 1.928 + IMPLEMENT_INTEL_DRIVER_BLOCKLIST(DRIVER_OS_WINDOWS_XP, IntelGMA900, V(6,14,10,4764)); 1.929 + IMPLEMENT_INTEL_DRIVER_BLOCKLIST(DRIVER_OS_WINDOWS_XP, IntelGMA950, V(6,14,10,4926)); 1.930 + IMPLEMENT_INTEL_DRIVER_BLOCKLIST(DRIVER_OS_WINDOWS_XP, IntelGMA3150, V(6,14,10,5134)); 1.931 + IMPLEMENT_INTEL_DRIVER_BLOCKLIST(DRIVER_OS_WINDOWS_XP, IntelGMAX3000, V(6,14,10,5218)); 1.932 + IMPLEMENT_INTEL_DRIVER_BLOCKLIST(DRIVER_OS_WINDOWS_XP, IntelGMAX4500HD, V(6,14,10,4969)); 1.933 + 1.934 + // StrechRect seems to suffer from precision issues which leads to artifacting 1.935 + // during content drawing starting with at least version 6.14.10.5082 1.936 + // and going until 6.14.10.5218. See bug 919454 and bug 949275 for more info. 1.937 + APPEND_TO_DRIVER_BLOCKLIST_RANGE(DRIVER_OS_WINDOWS_XP, 1.938 + const_cast<nsAString&>(GfxDriverInfo::GetDeviceVendor(VendorIntel)), 1.939 + const_cast<GfxDeviceFamily*>(GfxDriverInfo::GetDeviceFamily(IntelGMAX4500HD)), 1.940 + GfxDriverInfo::allFeatures, nsIGfxInfo::FEATURE_BLOCKED_DRIVER_VERSION, 1.941 + DRIVER_BETWEEN_EXCLUSIVE, V(6,14,10,5076), V(6,14,10,5218), "6.14.10.5218"); 1.942 + 1.943 + IMPLEMENT_INTEL_DRIVER_BLOCKLIST(DRIVER_OS_WINDOWS_VISTA, IntelGMA500, V(3,0,20,3200)); 1.944 + IMPLEMENT_INTEL_DRIVER_BLOCKLIST(DRIVER_OS_WINDOWS_VISTA, IntelGMA900, GfxDriverInfo::allDriverVersions); 1.945 + IMPLEMENT_INTEL_DRIVER_BLOCKLIST(DRIVER_OS_WINDOWS_VISTA, IntelGMA950, V(7,14,10,1504)); 1.946 + IMPLEMENT_INTEL_DRIVER_BLOCKLIST(DRIVER_OS_WINDOWS_VISTA, IntelGMA3150, V(7,14,10,1910)); 1.947 + IMPLEMENT_INTEL_DRIVER_BLOCKLIST(DRIVER_OS_WINDOWS_VISTA, IntelGMAX3000, V(7,15,10,1666)); 1.948 + IMPLEMENT_INTEL_DRIVER_BLOCKLIST(DRIVER_OS_WINDOWS_VISTA, IntelGMAX4500HD, V(7,15,10,1666)); 1.949 + 1.950 + IMPLEMENT_INTEL_DRIVER_BLOCKLIST(DRIVER_OS_WINDOWS_7, IntelGMA500, V(5,0,0,2026)); 1.951 + IMPLEMENT_INTEL_DRIVER_BLOCKLIST(DRIVER_OS_WINDOWS_7, IntelGMA900, GfxDriverInfo::allDriverVersions); 1.952 + IMPLEMENT_INTEL_DRIVER_BLOCKLIST(DRIVER_OS_WINDOWS_7, IntelGMA950, V(8,15,10,1930)); 1.953 + IMPLEMENT_INTEL_DRIVER_BLOCKLIST(DRIVER_OS_WINDOWS_7, IntelGMA3150, V(8,14,10,1972)); 1.954 + IMPLEMENT_INTEL_DRIVER_BLOCKLIST(DRIVER_OS_WINDOWS_7, IntelGMAX3000, V(7,15,10,1666)); 1.955 + IMPLEMENT_INTEL_DRIVER_BLOCKLIST(DRIVER_OS_WINDOWS_7, IntelGMAX4500HD, V(7,15,10,1666)); 1.956 + 1.957 + /* OpenGL on any Intel hardware is discouraged */ 1.958 + APPEND_TO_DRIVER_BLOCKLIST2( DRIVER_OS_ALL, 1.959 + (nsAString&) GfxDriverInfo::GetDeviceVendor(VendorIntel), GfxDriverInfo::allDevices, 1.960 + nsIGfxInfo::FEATURE_OPENGL_LAYERS, nsIGfxInfo::FEATURE_DISCOURAGED, 1.961 + DRIVER_LESS_THAN, GfxDriverInfo::allDriverVersions ); 1.962 + APPEND_TO_DRIVER_BLOCKLIST2( DRIVER_OS_ALL, 1.963 + (nsAString&) GfxDriverInfo::GetDeviceVendor(VendorIntel), GfxDriverInfo::allDevices, 1.964 + nsIGfxInfo::FEATURE_WEBGL_OPENGL, nsIGfxInfo::FEATURE_DISCOURAGED, 1.965 + DRIVER_LESS_THAN, GfxDriverInfo::allDriverVersions ); 1.966 + 1.967 + /* Disable D2D on Win7 on Intel HD Graphics on driver <= 8.15.10.2302 1.968 + * See bug 806786 1.969 + */ 1.970 + APPEND_TO_DRIVER_BLOCKLIST2( DRIVER_OS_WINDOWS_7, 1.971 + (nsAString&) GfxDriverInfo::GetDeviceVendor(VendorIntel), (GfxDeviceFamily*) GfxDriverInfo::GetDeviceFamily(IntelMobileHDGraphics), 1.972 + nsIGfxInfo::FEATURE_DIRECT2D, nsIGfxInfo::FEATURE_BLOCKED_DRIVER_VERSION, 1.973 + DRIVER_LESS_THAN_OR_EQUAL, V(8,15,10,2302) ); 1.974 + 1.975 + /* Disable D2D on Win8 on Intel HD Graphics on driver <= 8.15.10.2302 1.976 + * See bug 804144 and 863683 1.977 + */ 1.978 + APPEND_TO_DRIVER_BLOCKLIST2( DRIVER_OS_WINDOWS_8, 1.979 + (nsAString&) GfxDriverInfo::GetDeviceVendor(VendorIntel), (GfxDeviceFamily*) GfxDriverInfo::GetDeviceFamily(IntelMobileHDGraphics), 1.980 + nsIGfxInfo::FEATURE_DIRECT2D, nsIGfxInfo::FEATURE_BLOCKED_DRIVER_VERSION, 1.981 + DRIVER_LESS_THAN_OR_EQUAL, V(8,15,10,2302) ); 1.982 + 1.983 + /* Disable D3D9 layers on NVIDIA 6100/6150/6200 series due to glitches 1.984 + * whilst scrolling. See bugs: 612007, 644787 & 645872. 1.985 + */ 1.986 + APPEND_TO_DRIVER_BLOCKLIST2( DRIVER_OS_ALL, 1.987 + (nsAString&) GfxDriverInfo::GetDeviceVendor(VendorNVIDIA), (GfxDeviceFamily*) GfxDriverInfo::GetDeviceFamily(NvidiaBlockD3D9Layers), 1.988 + nsIGfxInfo::FEATURE_DIRECT3D_9_LAYERS, nsIGfxInfo::FEATURE_BLOCKED_DEVICE, 1.989 + DRIVER_LESS_THAN, GfxDriverInfo::allDriverVersions ); 1.990 + 1.991 + /* Microsoft RemoteFX; blocked less than 6.2.0.0 */ 1.992 + APPEND_TO_DRIVER_BLOCKLIST( DRIVER_OS_ALL, 1.993 + (nsAString&) GfxDriverInfo::GetDeviceVendor(VendorMicrosoft), GfxDriverInfo::allDevices, 1.994 + GfxDriverInfo::allFeatures, nsIGfxInfo::FEATURE_BLOCKED_DRIVER_VERSION, 1.995 + DRIVER_LESS_THAN, V(6,2,0,0), "< 6.2.0.0" ); 1.996 + } 1.997 + return *mDriverInfo; 1.998 +} 1.999 + 1.1000 +nsresult 1.1001 +GfxInfo::GetFeatureStatusImpl(int32_t aFeature, 1.1002 + int32_t *aStatus, 1.1003 + nsAString & aSuggestedDriverVersion, 1.1004 + const nsTArray<GfxDriverInfo>& aDriverInfo, 1.1005 + OperatingSystem* aOS /* = nullptr */) 1.1006 +{ 1.1007 + NS_ENSURE_ARG_POINTER(aStatus); 1.1008 + aSuggestedDriverVersion.SetIsVoid(true); 1.1009 + OperatingSystem os = WindowsVersionToOperatingSystem(mWindowsVersion); 1.1010 + *aStatus = nsIGfxInfo::FEATURE_STATUS_UNKNOWN; 1.1011 + if (aOS) 1.1012 + *aOS = os; 1.1013 + 1.1014 + // Don't evaluate special cases if we're checking the downloaded blocklist. 1.1015 + if (!aDriverInfo.Length()) { 1.1016 + nsAutoString adapterVendorID; 1.1017 + nsAutoString adapterDeviceID; 1.1018 + nsAutoString adapterDriverVersionString; 1.1019 + if (NS_FAILED(GetAdapterVendorID(adapterVendorID)) || 1.1020 + NS_FAILED(GetAdapterDeviceID(adapterDeviceID)) || 1.1021 + NS_FAILED(GetAdapterDriverVersion(adapterDriverVersionString))) 1.1022 + { 1.1023 + return NS_ERROR_FAILURE; 1.1024 + } 1.1025 + 1.1026 + if (!adapterVendorID.Equals(GfxDriverInfo::GetDeviceVendor(VendorIntel), nsCaseInsensitiveStringComparator()) && 1.1027 + !adapterVendorID.Equals(GfxDriverInfo::GetDeviceVendor(VendorNVIDIA), nsCaseInsensitiveStringComparator()) && 1.1028 + !adapterVendorID.Equals(GfxDriverInfo::GetDeviceVendor(VendorAMD), nsCaseInsensitiveStringComparator()) && 1.1029 + !adapterVendorID.Equals(GfxDriverInfo::GetDeviceVendor(VendorATI), nsCaseInsensitiveStringComparator()) && 1.1030 + !adapterVendorID.Equals(GfxDriverInfo::GetDeviceVendor(VendorMicrosoft), nsCaseInsensitiveStringComparator()) && 1.1031 + // FIXME - these special hex values are currently used in xpcshell tests introduced by 1.1032 + // bug 625160 patch 8/8. Maybe these tests need to be adjusted now that we're only whitelisting 1.1033 + // intel/ati/nvidia. 1.1034 + !adapterVendorID.LowerCaseEqualsLiteral("0xabcd") && 1.1035 + !adapterVendorID.LowerCaseEqualsLiteral("0xdcba") && 1.1036 + !adapterVendorID.LowerCaseEqualsLiteral("0xabab") && 1.1037 + !adapterVendorID.LowerCaseEqualsLiteral("0xdcdc")) 1.1038 + { 1.1039 + *aStatus = FEATURE_BLOCKED_DEVICE; 1.1040 + return NS_OK; 1.1041 + } 1.1042 + 1.1043 + uint64_t driverVersion; 1.1044 + if (!ParseDriverVersion(adapterDriverVersionString, &driverVersion)) { 1.1045 + return NS_ERROR_FAILURE; 1.1046 + } 1.1047 + 1.1048 + // special-case the WinXP test slaves: they have out-of-date drivers, but we still want to 1.1049 + // whitelist them, actually we do know that this combination of device and driver version 1.1050 + // works well. 1.1051 + if (mWindowsVersion == kWindowsXP && 1.1052 + adapterVendorID.Equals(GfxDriverInfo::GetDeviceVendor(VendorNVIDIA), nsCaseInsensitiveStringComparator()) && 1.1053 + adapterDeviceID.LowerCaseEqualsLiteral("0x0861") && // GeForce 9400 1.1054 + driverVersion == V(6,14,11,7756)) 1.1055 + { 1.1056 + *aStatus = FEATURE_NO_INFO; 1.1057 + return NS_OK; 1.1058 + } 1.1059 + 1.1060 + // Windows Server 2003 should be just like Windows XP for present purpose, but still has a different version number. 1.1061 + // OTOH Windows Server 2008 R1 and R2 already have the same version numbers as Vista and Seven respectively 1.1062 + if (os == DRIVER_OS_WINDOWS_SERVER_2003) 1.1063 + os = DRIVER_OS_WINDOWS_XP; 1.1064 + 1.1065 + if (mHasDriverVersionMismatch) { 1.1066 + if (aFeature == nsIGfxInfo::FEATURE_DIRECT3D_10_LAYERS || 1.1067 + aFeature == nsIGfxInfo::FEATURE_DIRECT3D_10_1_LAYERS || 1.1068 + aFeature == nsIGfxInfo::FEATURE_DIRECT2D) 1.1069 + { 1.1070 + *aStatus = nsIGfxInfo::FEATURE_BLOCKED_DRIVER_VERSION; 1.1071 + return NS_OK; 1.1072 + } 1.1073 + } 1.1074 + } 1.1075 + 1.1076 + return GfxInfoBase::GetFeatureStatusImpl(aFeature, aStatus, aSuggestedDriverVersion, aDriverInfo, &os); 1.1077 +} 1.1078 + 1.1079 +#ifdef DEBUG 1.1080 + 1.1081 +// Implement nsIGfxInfoDebug 1.1082 + 1.1083 +/* void spoofVendorID (in DOMString aVendorID); */ 1.1084 +NS_IMETHODIMP GfxInfo::SpoofVendorID(const nsAString & aVendorID) 1.1085 +{ 1.1086 + mAdapterVendorID = aVendorID; 1.1087 + return NS_OK; 1.1088 +} 1.1089 + 1.1090 +/* void spoofDeviceID (in unsigned long aDeviceID); */ 1.1091 +NS_IMETHODIMP GfxInfo::SpoofDeviceID(const nsAString & aDeviceID) 1.1092 +{ 1.1093 + mAdapterDeviceID = aDeviceID; 1.1094 + return NS_OK; 1.1095 +} 1.1096 + 1.1097 +/* void spoofDriverVersion (in DOMString aDriverVersion); */ 1.1098 +NS_IMETHODIMP GfxInfo::SpoofDriverVersion(const nsAString & aDriverVersion) 1.1099 +{ 1.1100 + mDriverVersion = aDriverVersion; 1.1101 + return NS_OK; 1.1102 +} 1.1103 + 1.1104 +/* void spoofOSVersion (in unsigned long aVersion); */ 1.1105 +NS_IMETHODIMP GfxInfo::SpoofOSVersion(uint32_t aVersion) 1.1106 +{ 1.1107 + mWindowsVersion = aVersion; 1.1108 + return NS_OK; 1.1109 +} 1.1110 + 1.1111 +#endif