Bug 699482: refactored GfxDriverInfo init to happen after global init r=bjacob

This patch moves all static initialization of GfxDriverInfo and DeviceFamily
classes to the point that they're actually used. It also converts all static
GfxDriverInfo arrays into nsTArray<GfxDriverInfo> so that they can be used
interchangeably with the downloadable blocklist.

This patch also introduces a new phase of blocklist checking called
BEING_PROCESSED, which is the status set when a blocklist check is currently
being processed. NO_INFO now only means that we have confirmed that a device is
not blocked.
This commit is contained in:
Doug Sherk 2011-12-14 21:02:59 -08:00
parent 896dcba95d
commit 0696522f34
14 changed files with 535 additions and 440 deletions

View File

@ -225,4 +225,4 @@
</gfxItems> </gfxItems>
</blocklist> </blocklist>

View File

@ -114,19 +114,22 @@ interface nsIGfxInfo : nsISupports
/* /*
* A set of return values from GetFeatureStatus * A set of return values from GetFeatureStatus
*/ */
/* We don't explicitly block or discourage the feature. Which means we'll try getting it from the /* We don't explicitly block or discourage the feature. Which means we'll try getting it from the
* hardware, and see what happens. */ * hardware, and see what happens. */
const long FEATURE_NO_INFO = 1; const long FEATURE_NO_INFO = 1;
/* We don't know the status of the feature yet. The analysis probably hasn't finished yet. */
const long FEATURE_STATUS_UNKNOWN = 2;
/* This feature is blocked on this driver version. Updating driver will typically unblock it. */ /* This feature is blocked on this driver version. Updating driver will typically unblock it. */
const long FEATURE_BLOCKED_DRIVER_VERSION = 2; const long FEATURE_BLOCKED_DRIVER_VERSION = 3;
/* This feature is blocked on this device, regardless of driver version. /* This feature is blocked on this device, regardless of driver version.
* Typically means we hit too many driver crashes without a good reason to hope for them to * Typically means we hit too many driver crashes without a good reason to hope for them to
* get fixed soon. */ * get fixed soon. */
const long FEATURE_BLOCKED_DEVICE = 3; const long FEATURE_BLOCKED_DEVICE = 4;
/* This feature is available and can be used, but is not suggested (e.g. shouldn't be used by default */ /* This feature is available and can be used, but is not suggested (e.g. shouldn't be used by default */
const long FEATURE_DISCOURAGED = 4; const long FEATURE_DISCOURAGED = 5;
/* This feature is blocked on this OS version. */ /* This feature is blocked on this OS version. */
const long FEATURE_BLOCKED_OS_VERSION = 5; const long FEATURE_BLOCKED_OS_VERSION = 6;
/** /**
* Ask about a feature, and return the status of that feature * Ask about a feature, and return the status of that feature

View File

@ -274,30 +274,30 @@ GfxInfo::AddOpenGLCrashReportAnnotations()
#endif #endif
} }
static GfxDriverInfo gDriverInfo[] = { const nsTArray<GfxDriverInfo>&
GfxDriverInfo()
};
const GfxDriverInfo*
GfxInfo::GetGfxDriverInfo() GfxInfo::GetGfxDriverInfo()
{ {
return &gDriverInfo[0]; // Nothing here yet.
//if (!mDriverInfo->Length()) {
//
//}
return *mDriverInfo;
} }
nsresult nsresult
GfxInfo::GetFeatureStatusImpl(PRInt32 aFeature, GfxInfo::GetFeatureStatusImpl(PRInt32 aFeature,
PRInt32 *aStatus, PRInt32 *aStatus,
nsAString & aSuggestedDriverVersion, nsAString & aSuggestedDriverVersion,
GfxDriverInfo* aDriverInfo /* = nsnull */, const nsTArray<GfxDriverInfo>& aDriverInfo,
OperatingSystem* aOS /* = nsnull */) OperatingSystem* aOS /* = nsnull */)
{ {
PRInt32 status = nsIGfxInfo::FEATURE_NO_INFO; PRInt32 status = nsIGfxInfo::FEATURE_STATUS_UNKNOWN;
aSuggestedDriverVersion.SetIsVoid(true); aSuggestedDriverVersion.SetIsVoid(true);
// For now, we don't implement the downloaded blacklist. // For now, we don't implement the downloaded blacklist.
if (aDriverInfo) { if (aDriverInfo.Length()) {
*aStatus = status; *aStatus = nsIGfxInfo::FEATURE_NO_INFO;
return NS_OK; return NS_OK;
} }
@ -326,6 +326,12 @@ GfxInfo::GetFeatureStatusImpl(PRInt32 aFeature,
*aOS = os; *aOS = os;
// XXX disabled for now as this calls GetAdapterVendorID and friends, which currently crash on Android, see bug 700124 // XXX disabled for now as this calls GetAdapterVendorID and friends, which currently crash on Android, see bug 700124
// return GfxInfoBase::GetFeatureStatusImpl(aFeature, aStatus, aSuggestedDriverVersion, aDriverInfo, &os); // FIXME: if this gets fixed, the line setting *aStatus must be removed
#if 0
return GfxInfoBase::GetFeatureStatusImpl(aFeature, aStatus, aSuggestedDriverVersion, aDriverInfo, &os);
#else
if (status == nsIGfxInfo::FEATURE_STATUS_UNKNOWN)
*aStatus = nsIGfxInfo::FEATURE_NO_INFO;
#endif
return NS_OK; return NS_OK;
} }

View File

@ -83,9 +83,9 @@ protected:
virtual nsresult GetFeatureStatusImpl(PRInt32 aFeature, virtual nsresult GetFeatureStatusImpl(PRInt32 aFeature,
PRInt32 *aStatus, PRInt32 *aStatus,
nsAString & aSuggestedDriverVersion, nsAString & aSuggestedDriverVersion,
GfxDriverInfo* aDriverInfo = nsnull, const nsTArray<GfxDriverInfo>& aDriverInfo,
OperatingSystem* aOS = nsnull); OperatingSystem* aOS = nsnull);
virtual const GfxDriverInfo* GetGfxDriverInfo(); virtual const nsTArray<GfxDriverInfo>& GetGfxDriverInfo();
private: private:

View File

@ -85,9 +85,9 @@ protected:
virtual nsresult GetFeatureStatusImpl(PRInt32 aFeature, virtual nsresult GetFeatureStatusImpl(PRInt32 aFeature,
PRInt32 *aStatus, PRInt32 *aStatus,
nsAString & aSuggestedDriverVersion, nsAString & aSuggestedDriverVersion,
GfxDriverInfo* aDriverInfo = nsnull, const nsTArray<GfxDriverInfo>& aDriverInfo,
OperatingSystem* aOS = nsnull); OperatingSystem* aOS = nsnull);
virtual const GfxDriverInfo* GetGfxDriverInfo(); virtual const nsTArray<GfxDriverInfo>& GetGfxDriverInfo();
private: private:

View File

@ -356,30 +356,21 @@ GfxInfo::AddCrashReportAnnotations()
#endif #endif
} }
static GfxDriverInfo gDriverInfo[] = { // We don't support checking driver versions on Mac.
// We don't support checking driver versions on Mac. #define IMPLEMENT_MAC_DRIVER_BLOCKLIST(os, vendor, device, features, blockOn) \
#define IMPLEMENT_MAC_DRIVER_BLOCKLIST(os, vendor, device, features, blockOn) \ APPEND_TO_DRIVER_BLOCKLIST(os, vendor, device, features, blockOn, \
GfxDriverInfo(os, vendor, device, features, blockOn, \ DRIVER_UNKNOWN_COMPARISON, V(0,0,0,0), "")
DRIVER_UNKNOWN_COMPARISON, V(0,0,0,0), ""),
// Example use of macro.
//IMPLEMENT_MAC_DRIVER_BLOCKLIST(DRIVER_OS_OS_X_10_7,
// GfxDriverInfo::vendorATI, GfxDriverInfo::allDevices,
// GfxDriverInfo::allFeatures, nsIGfxInfo::FEATURE_BLOCKED_OS_VERSION)
// Block all ATI cards from using MSAA, except for two devices that have const nsTArray<GfxDriverInfo>&
// special exceptions in the GetFeatureStatusImpl() function.
IMPLEMENT_MAC_DRIVER_BLOCKLIST(DRIVER_OS_ALL,
GfxDriverInfo::vendorATI, GfxDriverInfo::allDevices,
nsIGfxInfo::FEATURE_WEBGL_MSAA, nsIGfxInfo::FEATURE_BLOCKED_OS_VERSION)
GfxDriverInfo()
};
const GfxDriverInfo*
GfxInfo::GetGfxDriverInfo() GfxInfo::GetGfxDriverInfo()
{ {
return &gDriverInfo[0]; if (!mDriverInfo->Length()) {
IMPLEMENT_MAC_DRIVER_BLOCKLIST(DRIVER_OS_ALL,
GfxDriverInfo::vendorATI, GfxDriverInfo::allDevices,
nsIGfxInfo::FEATURE_WEBGL_MSAA, nsIGfxInfo::FEATURE_BLOCKED_OS_VERSION);
}
return *mDriverInfo;
} }
static OperatingSystem static OperatingSystem
@ -401,14 +392,14 @@ nsresult
GfxInfo::GetFeatureStatusImpl(PRInt32 aFeature, GfxInfo::GetFeatureStatusImpl(PRInt32 aFeature,
PRInt32* aStatus, PRInt32* aStatus,
nsAString& aSuggestedDriverVersion, nsAString& aSuggestedDriverVersion,
GfxDriverInfo* aDriverInfo /* = nsnull */, const nsTArray<GfxDriverInfo>& aDriverInfo,
OperatingSystem* aOS /* = nsnull */) OperatingSystem* aOS /* = nsnull */)
{ {
NS_ENSURE_ARG_POINTER(aStatus); NS_ENSURE_ARG_POINTER(aStatus);
aSuggestedDriverVersion.SetIsVoid(true); aSuggestedDriverVersion.SetIsVoid(true);
PRInt32 status = nsIGfxInfo::FEATURE_NO_INFO; PRInt32 status = nsIGfxInfo::FEATURE_STATUS_UNKNOWN;
OperatingSystem os = OSXVersionToOperatingSystem(nsToolkit::OSXVersion()); OperatingSystem os = OSXVersionToOperatingSystem(nsToolkit::OSXVersion());

View File

@ -794,118 +794,6 @@ GfxInfo::AddCrashReportAnnotations()
#endif #endif
} }
static const GfxDriverInfo gDriverInfo[] = {
/*
* Notice that the first match defines the result. So always implement special cases firsts and general case last.
*/
/*
* NVIDIA entries
*/
GfxDriverInfo( DRIVER_OS_WINDOWS_XP,
GfxDriverInfo::vendorNVIDIA, GfxDriverInfo::allDevices,
GfxDriverInfo::allFeatures, nsIGfxInfo::FEATURE_BLOCKED_DRIVER_VERSION,
DRIVER_LESS_THAN, V(6,14,12,5721), "257.21" ),
GfxDriverInfo( DRIVER_OS_WINDOWS_VISTA,
GfxDriverInfo::vendorNVIDIA, GfxDriverInfo::allDevices,
GfxDriverInfo::allFeatures, nsIGfxInfo::FEATURE_BLOCKED_DRIVER_VERSION,
DRIVER_LESS_THAN, V(8,17,12,5721), "257.21" ),
GfxDriverInfo( DRIVER_OS_WINDOWS_7,
GfxDriverInfo::vendorNVIDIA, GfxDriverInfo::allDevices,
GfxDriverInfo::allFeatures, nsIGfxInfo::FEATURE_BLOCKED_DRIVER_VERSION,
DRIVER_LESS_THAN, V(8,17,12,5721), "257.21" ),
/* Disable D3D9 layers on NVIDIA 6100/6150/6200 series due to glitches
* whilst scrolling. See bugs: 612007, 644787 & 645872.
*/
GfxDriverInfo( DRIVER_OS_ALL,
GfxDriverInfo::vendorNVIDIA, (GfxDeviceFamily) deviceFamilyNvidiaBlockD3D9Layers,
nsIGfxInfo::FEATURE_DIRECT3D_9_LAYERS, nsIGfxInfo::FEATURE_BLOCKED_DEVICE,
DRIVER_LESS_THAN, GfxDriverInfo::allDriverVersions ),
/*
* AMD/ATI entries
*/
GfxDriverInfo( DRIVER_OS_ALL,
GfxDriverInfo::vendorATI, GfxDriverInfo::allDevices,
GfxDriverInfo::allFeatures, nsIGfxInfo::FEATURE_BLOCKED_DRIVER_VERSION,
DRIVER_LESS_THAN, V(8,741,0,0), "10.6" ),
GfxDriverInfo( DRIVER_OS_ALL,
GfxDriverInfo::vendorAMD, GfxDriverInfo::allDevices,
GfxDriverInfo::allFeatures, nsIGfxInfo::FEATURE_BLOCKED_DRIVER_VERSION,
DRIVER_LESS_THAN, V(8,741,0,0), "10.6" ),
/* OpenGL on any ATI/AMD hardware is discouraged
* See:
* bug 619773 - WebGL: Crash with blue screen : "NMI: Parity Check / Memory Parity Error"
* bugs 584403, 584404, 620924 - crashes in atioglxx
* + many complaints about incorrect rendering
*/
GfxDriverInfo( DRIVER_OS_ALL,
GfxDriverInfo::vendorATI, GfxDriverInfo::allDevices,
nsIGfxInfo::FEATURE_OPENGL_LAYERS, nsIGfxInfo::FEATURE_DISCOURAGED,
DRIVER_LESS_THAN, GfxDriverInfo::allDriverVersions ),
GfxDriverInfo( DRIVER_OS_ALL,
GfxDriverInfo::vendorATI, GfxDriverInfo::allDevices,
nsIGfxInfo::FEATURE_WEBGL_OPENGL, nsIGfxInfo::FEATURE_DISCOURAGED,
DRIVER_LESS_THAN, GfxDriverInfo::allDriverVersions ),
GfxDriverInfo( DRIVER_OS_ALL,
GfxDriverInfo::vendorAMD, GfxDriverInfo::allDevices,
nsIGfxInfo::FEATURE_OPENGL_LAYERS, nsIGfxInfo::FEATURE_DISCOURAGED,
DRIVER_LESS_THAN, GfxDriverInfo::allDriverVersions ),
GfxDriverInfo( DRIVER_OS_ALL,
GfxDriverInfo::vendorAMD, GfxDriverInfo::allDevices,
nsIGfxInfo::FEATURE_WEBGL_OPENGL, nsIGfxInfo::FEATURE_DISCOURAGED,
DRIVER_LESS_THAN, GfxDriverInfo::allDriverVersions ),
/*
* Intel entries
*/
/* implement the blocklist from bug 594877
* Block all features on any drivers before this, as there's a crash when a MS Hotfix is installed.
* The crash itself is Direct2D-related, but for safety we block all features.
*/
#define IMPLEMENT_INTEL_DRIVER_BLOCKLIST(winVer, devFamily, driverVer) \
GfxDriverInfo( winVer, \
GfxDriverInfo::vendorIntel, (GfxDeviceFamily) devFamily, \
GfxDriverInfo::allFeatures, nsIGfxInfo::FEATURE_BLOCKED_DRIVER_VERSION, \
DRIVER_LESS_THAN, driverVer ),
IMPLEMENT_INTEL_DRIVER_BLOCKLIST(DRIVER_OS_WINDOWS_XP, deviceFamilyIntelGMA500, V(6,14,11,1018))
IMPLEMENT_INTEL_DRIVER_BLOCKLIST(DRIVER_OS_WINDOWS_XP, deviceFamilyIntelGMA900, V(6,14,10,4764))
IMPLEMENT_INTEL_DRIVER_BLOCKLIST(DRIVER_OS_WINDOWS_XP, deviceFamilyIntelGMA950, V(6,14,10,4926))
IMPLEMENT_INTEL_DRIVER_BLOCKLIST(DRIVER_OS_WINDOWS_XP, deviceFamilyIntelGMA3150, V(6,14,10,5260))
IMPLEMENT_INTEL_DRIVER_BLOCKLIST(DRIVER_OS_WINDOWS_XP, deviceFamilyIntelGMAX3000, V(6,14,10,5218))
IMPLEMENT_INTEL_DRIVER_BLOCKLIST(DRIVER_OS_WINDOWS_XP, deviceFamilyIntelGMAX4500HD, V(6,14,10,5284))
IMPLEMENT_INTEL_DRIVER_BLOCKLIST(DRIVER_OS_WINDOWS_VISTA, deviceFamilyIntelGMA500, V(7,14,10,1006))
IMPLEMENT_INTEL_DRIVER_BLOCKLIST(DRIVER_OS_WINDOWS_VISTA, deviceFamilyIntelGMA900, GfxDriverInfo::allDriverVersions)
IMPLEMENT_INTEL_DRIVER_BLOCKLIST(DRIVER_OS_WINDOWS_VISTA, deviceFamilyIntelGMA950, V(7,14,10,1504))
IMPLEMENT_INTEL_DRIVER_BLOCKLIST(DRIVER_OS_WINDOWS_VISTA, deviceFamilyIntelGMA3150, V(7,14,10,2124))
IMPLEMENT_INTEL_DRIVER_BLOCKLIST(DRIVER_OS_WINDOWS_VISTA, deviceFamilyIntelGMAX3000, V(7,15,10,1666))
IMPLEMENT_INTEL_DRIVER_BLOCKLIST(DRIVER_OS_WINDOWS_VISTA, deviceFamilyIntelGMAX4500HD, V(8,15,10,2202))
IMPLEMENT_INTEL_DRIVER_BLOCKLIST(DRIVER_OS_WINDOWS_7, deviceFamilyIntelGMA500, V(5,0,0,2026))
IMPLEMENT_INTEL_DRIVER_BLOCKLIST(DRIVER_OS_WINDOWS_7, deviceFamilyIntelGMA900, GfxDriverInfo::allDriverVersions)
IMPLEMENT_INTEL_DRIVER_BLOCKLIST(DRIVER_OS_WINDOWS_7, deviceFamilyIntelGMA950, V(8,15,10,1930))
IMPLEMENT_INTEL_DRIVER_BLOCKLIST(DRIVER_OS_WINDOWS_7, deviceFamilyIntelGMA3150, V(8,14,10,2117))
IMPLEMENT_INTEL_DRIVER_BLOCKLIST(DRIVER_OS_WINDOWS_7, deviceFamilyIntelGMAX3000, V(8,15,10,1930))
IMPLEMENT_INTEL_DRIVER_BLOCKLIST(DRIVER_OS_WINDOWS_7, deviceFamilyIntelGMAX4500HD, V(8,15,10,2202))
/* OpenGL on any Intel hardware is discouraged */
GfxDriverInfo( DRIVER_OS_ALL,
GfxDriverInfo::vendorIntel, GfxDriverInfo::allDevices,
nsIGfxInfo::FEATURE_OPENGL_LAYERS, nsIGfxInfo::FEATURE_DISCOURAGED,
DRIVER_LESS_THAN, GfxDriverInfo::allDriverVersions ),
GfxDriverInfo( DRIVER_OS_ALL,
GfxDriverInfo::vendorIntel, GfxDriverInfo::allDevices,
nsIGfxInfo::FEATURE_WEBGL_OPENGL, nsIGfxInfo::FEATURE_DISCOURAGED,
DRIVER_LESS_THAN, GfxDriverInfo::allDriverVersions ),
GfxDriverInfo()
};
static OperatingSystem static OperatingSystem
WindowsVersionToOperatingSystem(PRInt32 aWindowsVersion) WindowsVersionToOperatingSystem(PRInt32 aWindowsVersion)
{ {
@ -926,45 +814,149 @@ WindowsVersionToOperatingSystem(PRInt32 aWindowsVersion)
}; };
} }
const GfxDriverInfo* const nsTArray<GfxDriverInfo>&
GfxInfo::GetGfxDriverInfo() GfxInfo::GetGfxDriverInfo()
{ {
return &gDriverInfo[0]; if (!mDriverInfo->Length()) {
/*
* NVIDIA entries
*/
APPEND_TO_DRIVER_BLOCKLIST( DRIVER_OS_WINDOWS_XP,
GfxDriverInfo::vendorNVIDIA, GfxDriverInfo::allDevices,
GfxDriverInfo::allFeatures, nsIGfxInfo::FEATURE_BLOCKED_DRIVER_VERSION,
DRIVER_LESS_THAN, V(6,14,12,5721), "257.21" );
APPEND_TO_DRIVER_BLOCKLIST( DRIVER_OS_WINDOWS_VISTA,
GfxDriverInfo::vendorNVIDIA, GfxDriverInfo::allDevices,
GfxDriverInfo::allFeatures, nsIGfxInfo::FEATURE_BLOCKED_DRIVER_VERSION,
DRIVER_LESS_THAN, V(8,17,12,5721), "257.21" );
APPEND_TO_DRIVER_BLOCKLIST( DRIVER_OS_WINDOWS_7,
GfxDriverInfo::vendorNVIDIA, GfxDriverInfo::allDevices,
GfxDriverInfo::allFeatures, nsIGfxInfo::FEATURE_BLOCKED_DRIVER_VERSION,
DRIVER_LESS_THAN, V(8,17,12,5721), "257.21" );
/* Disable D3D9 layers on NVIDIA 6100/6150/6200 series due to glitches
* whilst scrolling. See bugs: 612007, 644787 & 645872.
*/
APPEND_TO_DRIVER_BLOCKLIST2( DRIVER_OS_ALL,
GfxDriverInfo::vendorNVIDIA, (GfxDeviceFamily) GfxDriverInfo::GetDeviceFamily(DeviceFamily::NvidiaBlockD3D9Layers),
nsIGfxInfo::FEATURE_DIRECT3D_9_LAYERS, nsIGfxInfo::FEATURE_BLOCKED_DEVICE,
DRIVER_LESS_THAN, GfxDriverInfo::allDriverVersions );
/*
* AMD/ATI entries
*/
APPEND_TO_DRIVER_BLOCKLIST( DRIVER_OS_ALL,
GfxDriverInfo::vendorATI, GfxDriverInfo::allDevices,
GfxDriverInfo::allFeatures, nsIGfxInfo::FEATURE_BLOCKED_DRIVER_VERSION,
DRIVER_LESS_THAN, V(8,741,0,0), "10.6" );
APPEND_TO_DRIVER_BLOCKLIST( DRIVER_OS_ALL,
GfxDriverInfo::vendorAMD, GfxDriverInfo::allDevices,
GfxDriverInfo::allFeatures, nsIGfxInfo::FEATURE_BLOCKED_DRIVER_VERSION,
DRIVER_LESS_THAN, V(8,741,0,0), "10.6" );
/* OpenGL on any ATI/AMD hardware is discouraged
* See:
* bug 619773 - WebGL: Crash with blue screen : "NMI: Parity Check / Memory Parity Error"
* bugs 584403, 584404, 620924 - crashes in atioglxx
* + many complaints about incorrect rendering
*/
APPEND_TO_DRIVER_BLOCKLIST2( DRIVER_OS_ALL,
GfxDriverInfo::vendorATI, GfxDriverInfo::allDevices,
nsIGfxInfo::FEATURE_OPENGL_LAYERS, nsIGfxInfo::FEATURE_DISCOURAGED,
DRIVER_LESS_THAN, GfxDriverInfo::allDriverVersions );
APPEND_TO_DRIVER_BLOCKLIST2( DRIVER_OS_ALL,
GfxDriverInfo::vendorATI, GfxDriverInfo::allDevices,
nsIGfxInfo::FEATURE_WEBGL_OPENGL, nsIGfxInfo::FEATURE_DISCOURAGED,
DRIVER_LESS_THAN, GfxDriverInfo::allDriverVersions );
APPEND_TO_DRIVER_BLOCKLIST2( DRIVER_OS_ALL,
GfxDriverInfo::vendorAMD, GfxDriverInfo::allDevices,
nsIGfxInfo::FEATURE_OPENGL_LAYERS, nsIGfxInfo::FEATURE_DISCOURAGED,
DRIVER_LESS_THAN, GfxDriverInfo::allDriverVersions );
APPEND_TO_DRIVER_BLOCKLIST2( DRIVER_OS_ALL,
GfxDriverInfo::vendorAMD, GfxDriverInfo::allDevices,
nsIGfxInfo::FEATURE_WEBGL_OPENGL, nsIGfxInfo::FEATURE_DISCOURAGED,
DRIVER_LESS_THAN, GfxDriverInfo::allDriverVersions );
/*
* Intel entries
*/
/* implement the blocklist from bug 594877
* Block all features on any drivers before this, as there's a crash when a MS Hotfix is installed.
* The crash itself is Direct2D-related, but for safety we block all features.
*/
#define IMPLEMENT_INTEL_DRIVER_BLOCKLIST(winVer, devFamily, driverVer) \
APPEND_TO_DRIVER_BLOCKLIST2( winVer, \
GfxDriverInfo::vendorIntel, (GfxDeviceFamily) GfxDriverInfo::GetDeviceFamily(devFamily), \
GfxDriverInfo::allFeatures, nsIGfxInfo::FEATURE_BLOCKED_DRIVER_VERSION, \
DRIVER_LESS_THAN, driverVer )
IMPLEMENT_INTEL_DRIVER_BLOCKLIST(DRIVER_OS_WINDOWS_XP, DeviceFamily::IntelGMA500, V(6,14,11,1018));
IMPLEMENT_INTEL_DRIVER_BLOCKLIST(DRIVER_OS_WINDOWS_XP, DeviceFamily::IntelGMA900, V(6,14,10,4764));
IMPLEMENT_INTEL_DRIVER_BLOCKLIST(DRIVER_OS_WINDOWS_XP, DeviceFamily::IntelGMA950, V(6,14,10,4926));
IMPLEMENT_INTEL_DRIVER_BLOCKLIST(DRIVER_OS_WINDOWS_XP, DeviceFamily::IntelGMA3150, V(6,14,10,5260));
IMPLEMENT_INTEL_DRIVER_BLOCKLIST(DRIVER_OS_WINDOWS_XP, DeviceFamily::IntelGMAX3000, V(6,14,10,5218));
IMPLEMENT_INTEL_DRIVER_BLOCKLIST(DRIVER_OS_WINDOWS_XP, DeviceFamily::IntelGMAX4500HD, V(6,14,10,5284));
IMPLEMENT_INTEL_DRIVER_BLOCKLIST(DRIVER_OS_WINDOWS_VISTA, DeviceFamily::IntelGMA500, V(7,14,10,1006));
IMPLEMENT_INTEL_DRIVER_BLOCKLIST(DRIVER_OS_WINDOWS_VISTA, DeviceFamily::IntelGMA900, GfxDriverInfo::allDriverVersions);
IMPLEMENT_INTEL_DRIVER_BLOCKLIST(DRIVER_OS_WINDOWS_VISTA, DeviceFamily::IntelGMA950, V(7,14,10,1504));
IMPLEMENT_INTEL_DRIVER_BLOCKLIST(DRIVER_OS_WINDOWS_VISTA, DeviceFamily::IntelGMA3150, V(7,14,10,2124));
IMPLEMENT_INTEL_DRIVER_BLOCKLIST(DRIVER_OS_WINDOWS_VISTA, DeviceFamily::IntelGMAX3000, V(7,15,10,1666));
IMPLEMENT_INTEL_DRIVER_BLOCKLIST(DRIVER_OS_WINDOWS_VISTA, DeviceFamily::IntelGMAX4500HD, V(8,15,10,2202));
IMPLEMENT_INTEL_DRIVER_BLOCKLIST(DRIVER_OS_WINDOWS_7, DeviceFamily::IntelGMA500, V(5,0,0,2026));
IMPLEMENT_INTEL_DRIVER_BLOCKLIST(DRIVER_OS_WINDOWS_7, DeviceFamily::IntelGMA900, GfxDriverInfo::allDriverVersions);
IMPLEMENT_INTEL_DRIVER_BLOCKLIST(DRIVER_OS_WINDOWS_7, DeviceFamily::IntelGMA950, V(8,15,10,1930));
IMPLEMENT_INTEL_DRIVER_BLOCKLIST(DRIVER_OS_WINDOWS_7, DeviceFamily::IntelGMA3150, V(8,14,10,2117));
IMPLEMENT_INTEL_DRIVER_BLOCKLIST(DRIVER_OS_WINDOWS_7, DeviceFamily::IntelGMAX3000, V(8,15,10,1930));
IMPLEMENT_INTEL_DRIVER_BLOCKLIST(DRIVER_OS_WINDOWS_7, DeviceFamily::IntelGMAX4500HD, V(8,15,10,2202));
/* OpenGL on any Intel hardware is discouraged */
APPEND_TO_DRIVER_BLOCKLIST2( DRIVER_OS_ALL,
GfxDriverInfo::vendorIntel, GfxDriverInfo::allDevices,
nsIGfxInfo::FEATURE_OPENGL_LAYERS, nsIGfxInfo::FEATURE_DISCOURAGED,
DRIVER_LESS_THAN, GfxDriverInfo::allDriverVersions );
APPEND_TO_DRIVER_BLOCKLIST2( DRIVER_OS_ALL,
GfxDriverInfo::vendorIntel, GfxDriverInfo::allDevices,
nsIGfxInfo::FEATURE_WEBGL_OPENGL, nsIGfxInfo::FEATURE_DISCOURAGED,
DRIVER_LESS_THAN, GfxDriverInfo::allDriverVersions );
}
return *mDriverInfo;
} }
nsresult nsresult
GfxInfo::GetFeatureStatusImpl(PRInt32 aFeature, GfxInfo::GetFeatureStatusImpl(PRInt32 aFeature,
PRInt32 *aStatus, PRInt32 *aStatus,
nsAString & aSuggestedDriverVersion, nsAString & aSuggestedDriverVersion,
GfxDriverInfo* aDriverInfo /* = nsnull */, const nsTArray<GfxDriverInfo>& aDriverInfo,
OperatingSystem* aOS /* = nsnull */) OperatingSystem* aOS /* = nsnull */)
{ {
*aStatus = nsIGfxInfo::FEATURE_NO_INFO;
aSuggestedDriverVersion.SetIsVoid(true); aSuggestedDriverVersion.SetIsVoid(true);
PRInt32 status = nsIGfxInfo::FEATURE_NO_INFO; PRInt32 status = nsIGfxInfo::FEATURE_STATUS_UNKNOWN;
PRUint32 adapterVendor = 0; PRUint32 adapterVendorID = 0;
PRUint32 adapterDeviceID = 0; PRUint32 adapterDeviceID = 0;
nsAutoString adapterDriverVersionString; nsAutoString adapterDriverVersionString;
if (NS_FAILED(GetAdapterVendorID(&adapterVendor)) || if (NS_FAILED(GetAdapterVendorID(&adapterVendorID)) ||
NS_FAILED(GetAdapterDeviceID(&adapterDeviceID)) || NS_FAILED(GetAdapterDeviceID(&adapterDeviceID)) ||
NS_FAILED(GetAdapterDriverVersion(adapterDriverVersionString))) NS_FAILED(GetAdapterDriverVersion(adapterDriverVersionString)))
{ {
return NS_ERROR_FAILURE; return NS_ERROR_FAILURE;
} }
if (adapterVendor != GfxDriverInfo::vendorIntel && if (adapterVendorID != GfxDriverInfo::vendorIntel &&
adapterVendor != GfxDriverInfo::vendorNVIDIA && adapterVendorID != GfxDriverInfo::vendorNVIDIA &&
adapterVendor != GfxDriverInfo::vendorAMD && adapterVendorID != GfxDriverInfo::vendorAMD &&
adapterVendor != GfxDriverInfo::vendorATI && adapterVendorID != GfxDriverInfo::vendorATI &&
// FIXME - these special hex values are currently used in xpcshell tests introduced by // FIXME - these special hex values are currently used in xpcshell tests introduced by
// bug 625160 patch 8/8. Maybe these tests need to be adjusted now that we're only whitelisting // bug 625160 patch 8/8. Maybe these tests need to be adjusted now that we're only whitelisting
// intel/ati/nvidia. // intel/ati/nvidia.
adapterVendor != 0xabcd && adapterVendorID != 0xabcd &&
adapterVendor != 0xdcba && adapterVendorID != 0xdcba &&
adapterVendor != 0xabab && adapterVendorID != 0xabab &&
adapterVendor != 0xdcdc) adapterVendorID != 0xdcdc)
{ {
*aStatus = FEATURE_BLOCKED_DEVICE; *aStatus = FEATURE_BLOCKED_DEVICE;
return NS_OK; return NS_OK;
@ -974,7 +966,19 @@ GfxInfo::GetFeatureStatusImpl(PRInt32 aFeature,
if (!ParseDriverVersion(adapterDriverVersionString, &driverVersion)) { if (!ParseDriverVersion(adapterDriverVersionString, &driverVersion)) {
return NS_ERROR_FAILURE; return NS_ERROR_FAILURE;
} }
// special-case the WinXP test slaves: they have out-of-date drivers, but we still want to
// whitelist them, actually we do know that this combination of device and driver version
// works well.
if (mWindowsVersion == gfxWindowsPlatform::kWindowsXP &&
adapterVendorID == GfxDriverInfo::vendorNVIDIA &&
adapterDeviceID == 0x0861 && // GeForce 9400
driverVersion == V(6,14,11,7756))
{
*aStatus = FEATURE_NO_INFO;
return NS_OK;
}
if (aFeature == FEATURE_DIRECT3D_9_LAYERS && if (aFeature == FEATURE_DIRECT3D_9_LAYERS &&
mWindowsVersion < gfxWindowsPlatform::kWindowsXP) mWindowsVersion < gfxWindowsPlatform::kWindowsXP)
{ {
@ -998,12 +1002,6 @@ GfxInfo::GetFeatureStatusImpl(PRInt32 aFeature,
if (os == DRIVER_OS_WINDOWS_SERVER_2003) if (os == DRIVER_OS_WINDOWS_SERVER_2003)
os = DRIVER_OS_WINDOWS_XP; os = DRIVER_OS_WINDOWS_XP;
const GfxDriverInfo *info;
if (aDriverInfo)
info = aDriverInfo;
else
info = &gDriverInfo[0];
if (mHasDriverVersionMismatch) { if (mHasDriverVersionMismatch) {
if (aFeature == nsIGfxInfo::FEATURE_DIRECT3D_10_LAYERS || if (aFeature == nsIGfxInfo::FEATURE_DIRECT3D_10_LAYERS ||
aFeature == nsIGfxInfo::FEATURE_DIRECT3D_10_1_LAYERS || aFeature == nsIGfxInfo::FEATURE_DIRECT3D_10_1_LAYERS ||

View File

@ -92,9 +92,9 @@ protected:
virtual nsresult GetFeatureStatusImpl(PRInt32 aFeature, virtual nsresult GetFeatureStatusImpl(PRInt32 aFeature,
PRInt32 *aStatus, PRInt32 *aStatus,
nsAString & aSuggestedDriverVersion, nsAString & aSuggestedDriverVersion,
GfxDriverInfo* aDriverInfo = nsnull, const nsTArray<GfxDriverInfo>& aDriverInfo,
OperatingSystem* aOS = nsnull); OperatingSystem* aOS = nsnull);
virtual const GfxDriverInfo* GetGfxDriverInfo(); virtual const nsTArray<GfxDriverInfo>& GetGfxDriverInfo();
private: private:

View File

@ -117,3 +117,131 @@ GfxDriverInfo::~GfxDriverInfo()
if (mDeleteDevices) if (mDeleteDevices)
delete[] mDevices; delete[] mDevices;
} }
const GfxDeviceFamily GfxDriverInfo::GetDeviceFamily(DeviceFamily id)
{
switch (id) {
case IntelGMA500: {
static const PRUint32 intelGMA500[] = {
0x8108, /* IntelGMA500_1 */
0x8109, /* IntelGMA500_2 */
0
};
return (const GfxDeviceFamily) &intelGMA500[0];
}
case IntelGMA900: {
static const PRUint32 intelGMA900[] = {
0x2582, /* IntelGMA900_1 */
0x2782, /* IntelGMA900_2 */
0x2592, /* IntelGMA900_3 */
0x2792, /* IntelGMA900_4 */
0
};
return (const GfxDeviceFamily) &intelGMA900[0];
}
case IntelGMA950: {
static const PRUint32 intelGMA950[] = {
0x2772, /* Intel945G_1 */
0x2776, /* Intel945G_2 */
0x27A2, /* Intel945_1 */
0x27A6, /* Intel945_2 */
0x27AE, /* Intel945_3 */
0
};
return (const GfxDeviceFamily) &intelGMA950[0];
}
case IntelGMA3150: {
static const PRUint32 intelGMA3150[] = {
0xA001, /* IntelGMA3150_Nettop_1 */
0xA002, /* IntelGMA3150_Nettop_2 */
0xA011, /* IntelGMA3150_Netbook_1 */
0xA012, /* IntelGMA3150_Netbook_2 */
0
};
return (const GfxDeviceFamily) &intelGMA3150[0];
}
case IntelGMAX3000: {
static const PRUint32 intelGMAX3000[] = {
0x2972, /* Intel946GZ_1 */
0x2973, /* Intel946GZ_2 */
0x2982, /* IntelG35_1 */
0x2983, /* IntelG35_2 */
0x2992, /* IntelQ965_1 */
0x2993, /* IntelQ965_2 */
0x29A2, /* IntelG965_1 */
0x29A3, /* IntelG965_2 */
0x29B2, /* IntelQ35_1 */
0x29B3, /* IntelQ35_2 */
0x29C2, /* IntelG33_1 */
0x29C3, /* IntelG33_2 */
0x29D2, /* IntelQ33_1 */
0x29D3, /* IntelQ33_2 */
0x2A02, /* IntelGL960_1 */
0x2A03, /* IntelGL960_2 */
0x2A12, /* IntelGM965_1 */
0x2A13, /* IntelGM965_2 */
0
};
return (const GfxDeviceFamily) &intelGMAX3000[0];
}
case IntelGMAX4500HD: {
static const PRUint32 intelGMAX4500HD[] = {
0x2A42, /* IntelGMA4500MHD_1 */
0x2A43, /* IntelGMA4500MHD_2 */
0x2E42, /* IntelB43_1 */
0x2E43, /* IntelB43_2 */
0x2E92, /* IntelB43_3 */
0x2E93, /* IntelB43_4 */
0x2E32, /* IntelG41_1 */
0x2E33, /* IntelG41_2 */
0x2E22, /* IntelG45_1 */
0x2E23, /* IntelG45_2 */
0x2E12, /* IntelQ45_1 */
0x2E13, /* IntelQ45_2 */
0x0042, /* IntelHDGraphics */
0x0046, /* IntelMobileHDGraphics */
0x0102, /* IntelSandyBridge_1 */
0x0106, /* IntelSandyBridge_2 */
0x0112, /* IntelSandyBridge_3 */
0x0116, /* IntelSandyBridge_4 */
0x0122, /* IntelSandyBridge_5 */
0x0126, /* IntelSandyBridge_6 */
0x010A, /* IntelSandyBridge_7 */
0x0080, /* IntelIvyBridge */
0
};
return (const GfxDeviceFamily) &intelGMAX4500HD[0];
}
case NvidiaBlockD3D9Layers: {
// Glitches whilst scrolling (see bugs 612007, 644787, 645872)
static const PRUint32 nvidiaBlockD3D9Layers[] = {
0x00f3, /* NV43 [GeForce 6200 (TM)] */
0x0146, /* NV43 [Geforce Go 6600TE/6200TE (TM)] */
0x014f, /* NV43 [GeForce 6200 (TM)] */
0x0161, /* NV44 [GeForce 6200 TurboCache (TM)] */
0x0162, /* NV44 [GeForce 6200SE TurboCache (TM)] */
0x0163, /* NV44 [GeForce 6200 LE (TM)] */
0x0164, /* NV44 [GeForce Go 6200 (TM)] */
0x0167, /* NV43 [GeForce Go 6200/6400 (TM)] */
0x0168, /* NV43 [GeForce Go 6200/6400 (TM)] */
0x0169, /* NV44 [GeForce 6250 (TM)] */
0x0222, /* NV44 [GeForce 6200 A-LE (TM)] */
0x0240, /* C51PV [GeForce 6150 (TM)] */
0x0241, /* C51 [GeForce 6150 LE (TM)] */
0x0244, /* C51 [Geforce Go 6150 (TM)] */
0x0245, /* C51 [Quadro NVS 210S/GeForce 6150LE (TM)] */
0x0247, /* C51 [GeForce Go 6100 (TM)] */
0x03d0, /* C61 [GeForce 6150SE nForce 430 (TM)] */
0x03d1, /* C61 [GeForce 6100 nForce 405 (TM)] */
0x03d2, /* C61 [GeForce 6100 nForce 400 (TM)] */
0x03d5, /* C61 [GeForce 6100 nForce 420 (TM)] */
0
};
return (const GfxDeviceFamily) &nvidiaBlockD3D9Layers[0];
}
default:
NS_WARNING("Invalid device family");
}
return nsnull;
}

View File

@ -43,6 +43,11 @@
#define V(a,b,c,d) GFX_DRIVER_VERSION(a,b,c,d) #define V(a,b,c,d) GFX_DRIVER_VERSION(a,b,c,d)
#define APPEND_TO_DRIVER_BLOCKLIST(os, vendor, devices, feature, featureStatus, driverComparator, driverVersion, suggestedVersion) \
mDriverInfo->AppendElement(GfxDriverInfo(os, vendor, devices, feature, featureStatus, driverComparator, driverVersion, suggestedVersion))
#define APPEND_TO_DRIVER_BLOCKLIST2(os, vendor, devices, feature, featureStatus, driverComparator, driverVersion) \
mDriverInfo->AppendElement(GfxDriverInfo(os, vendor, devices, feature, featureStatus, driverComparator, driverVersion))
namespace mozilla { namespace mozilla {
namespace widget { namespace widget {
@ -74,112 +79,18 @@ enum VersionComparisonOp {
DRIVER_UNKNOWN_COMPARISON DRIVER_UNKNOWN_COMPARISON
}; };
static const PRUint32 deviceFamilyIntelGMA500[] = { enum DeviceFamily {
0x8108, /* IntelGMA500_1 */ IntelGMA500,
0x8109, /* IntelGMA500_2 */ IntelGMA900,
0 IntelGMA950,
}; IntelGMA3150,
IntelGMAX3000,
static const PRUint32 deviceFamilyIntelGMA900[] = { IntelGMAX4500HD,
0x2582, /* IntelGMA900_1 */ NvidiaBlockD3D9Layers
0x2782, /* IntelGMA900_2 */
0x2592, /* IntelGMA900_3 */
0x2792, /* IntelGMA900_4 */
0
};
static const PRUint32 deviceFamilyIntelGMA950[] = {
0x2772, /* Intel945G_1 */
0x2776, /* Intel945G_2 */
0x27A2, /* Intel945_1 */
0x27A6, /* Intel945_2 */
0x27AE, /* Intel945_3 */
0
};
static const PRUint32 deviceFamilyIntelGMA3150[] = {
0xA001, /* IntelGMA3150_Nettop_1 */
0xA002, /* IntelGMA3150_Nettop_2 */
0xA011, /* IntelGMA3150_Netbook_1 */
0xA012, /* IntelGMA3150_Netbook_2 */
0
};
static const PRUint32 deviceFamilyIntelGMAX3000[] = {
0x2972, /* Intel946GZ_1 */
0x2973, /* Intel946GZ_2 */
0x2982, /* IntelG35_1 */
0x2983, /* IntelG35_2 */
0x2992, /* IntelQ965_1 */
0x2993, /* IntelQ965_2 */
0x29A2, /* IntelG965_1 */
0x29A3, /* IntelG965_2 */
0x29B2, /* IntelQ35_1 */
0x29B3, /* IntelQ35_2 */
0x29C2, /* IntelG33_1 */
0x29C3, /* IntelG33_2 */
0x29D2, /* IntelQ33_1 */
0x29D3, /* IntelQ33_2 */
0x2A02, /* IntelGL960_1 */
0x2A03, /* IntelGL960_2 */
0x2A12, /* IntelGM965_1 */
0x2A13, /* IntelGM965_2 */
0
};
static const PRUint32 deviceFamilyIntelGMAX4500HD[] = {
0x2A42, /* IntelGMA4500MHD_1 */
0x2A43, /* IntelGMA4500MHD_2 */
0x2E42, /* IntelB43_1 */
0x2E43, /* IntelB43_2 */
0x2E92, /* IntelB43_3 */
0x2E93, /* IntelB43_4 */
0x2E32, /* IntelG41_1 */
0x2E33, /* IntelG41_2 */
0x2E22, /* IntelG45_1 */
0x2E23, /* IntelG45_2 */
0x2E12, /* IntelQ45_1 */
0x2E13, /* IntelQ45_2 */
0x0042, /* IntelHDGraphics */
0x0046, /* IntelMobileHDGraphics */
0x0102, /* IntelSandyBridge_1 */
0x0106, /* IntelSandyBridge_2 */
0x0112, /* IntelSandyBridge_3 */
0x0116, /* IntelSandyBridge_4 */
0x0122, /* IntelSandyBridge_5 */
0x0126, /* IntelSandyBridge_6 */
0x010A, /* IntelSandyBridge_7 */
0x0080, /* IntelIvyBridge */
0
};
// Glitches whilst scrolling (see bugs 612007, 644787, 645872)
static const PRUint32 deviceFamilyNvidiaBlockD3D9Layers[] = {
0x00f3, /* NV43 [GeForce 6200 (TM)] */
0x0146, /* NV43 [Geforce Go 6600TE/6200TE (TM)] */
0x014f, /* NV43 [GeForce 6200 (TM)] */
0x0161, /* NV44 [GeForce 6200 TurboCache (TM)] */
0x0162, /* NV44 [GeForce 6200SE TurboCache (TM)] */
0x0163, /* NV44 [GeForce 6200 LE (TM)] */
0x0164, /* NV44 [GeForce Go 6200 (TM)] */
0x0167, /* NV43 [GeForce Go 6200/6400 (TM)] */
0x0168, /* NV43 [GeForce Go 6200/6400 (TM)] */
0x0169, /* NV44 [GeForce 6250 (TM)] */
0x0222, /* NV44 [GeForce 6200 A-LE (TM)] */
0x0240, /* C51PV [GeForce 6150 (TM)] */
0x0241, /* C51 [GeForce 6150 LE (TM)] */
0x0244, /* C51 [Geforce Go 6150 (TM)] */
0x0245, /* C51 [Quadro NVS 210S/GeForce 6150LE (TM)] */
0x0247, /* C51 [GeForce Go 6100 (TM)] */
0x03d0, /* C61 [GeForce 6150SE nForce 430 (TM)] */
0x03d1, /* C61 [GeForce 6100 nForce 405 (TM)] */
0x03d2, /* C61 [GeForce 6100 nForce 400 (TM)] */
0x03d5, /* C61 [GeForce 6100 nForce 420 (TM)] */
0
}; };
/* A zero-terminated array of devices to match, or all devices */ /* A zero-terminated array of devices to match, or all devices */
typedef PRUint32 *GfxDeviceFamily; typedef PRUint32* GfxDeviceFamily;
struct GfxDriverInfo struct GfxDriverInfo
{ {
@ -226,6 +137,8 @@ struct GfxDriverInfo
static PRUint32 vendorATI; static PRUint32 vendorATI;
const char *mSuggestedVersion; const char *mSuggestedVersion;
static const GfxDeviceFamily GetDeviceFamily(DeviceFamily id);
}; };
#define GFX_DRIVER_VERSION(a,b,c,d) \ #define GFX_DRIVER_VERSION(a,b,c,d) \

View File

@ -48,6 +48,7 @@
#include "nsAutoPtr.h" #include "nsAutoPtr.h"
#include "nsString.h" #include "nsString.h"
#include "mozilla/Services.h" #include "mozilla/Services.h"
#include "mozilla/Observer.h"
#include "nsIObserver.h" #include "nsIObserver.h"
#include "nsIObserverService.h" #include "nsIObserverService.h"
#include "nsIDOMElement.h" #include "nsIDOMElement.h"
@ -60,8 +61,52 @@
#include "nsExceptionHandler.h" #include "nsExceptionHandler.h"
#endif #endif
using namespace mozilla::widget;
using namespace mozilla; using namespace mozilla;
nsTArray<GfxDriverInfo>* GfxInfoBase::mDriverInfo;
bool GfxInfoBase::mDriverInfoObserverInitialized;
// Observes for shutdown so that the child GfxDriverInfo list is freed.
class ShutdownObserver : public nsIObserver
{
public:
ShutdownObserver() {}
virtual ~ShutdownObserver() {}
NS_DECL_ISUPPORTS
NS_IMETHOD Observe(nsISupports *subject, const char *aTopic,
const PRUnichar *aData)
{
MOZ_ASSERT(strcmp(aTopic, NS_XPCOM_SHUTDOWN_OBSERVER_ID) == 0);
if (GfxInfoBase::mDriverInfo) {
delete GfxInfoBase::mDriverInfo;
GfxInfoBase::mDriverInfo = nsnull;
}
return NS_OK;
}
};
NS_IMPL_ISUPPORTS1(ShutdownObserver, nsIObserver);
void InitGfxDriverInfoShutdownObserver()
{
if (GfxInfoBase::mDriverInfoObserverInitialized)
return;
GfxInfoBase::mDriverInfoObserverInitialized = true;
nsCOMPtr<nsIObserverService> observerService = services::GetObserverService();
if (!observerService) {
NS_WARNING("Could not get observer service!");
return;
}
ShutdownObserver *obs = new ShutdownObserver();
observerService->AddObserver(obs, NS_XPCOM_SHUTDOWN_OBSERVER_ID, false);
}
extern "C" { extern "C" {
void StoreSpline(int ax, int ay, int bx, int by, int cx, int cy, int dx, int dy); void StoreSpline(int ax, int ay, int bx, int by, int cx, int cy, int dx, int dy);
void CrashSpline(double tolerance, int ax, int ay, int bx, int by, int cx, int cy, int dx, int dy); void CrashSpline(double tolerance, int ax, int ay, int bx, int by, int cx, int cy, int dx, int dy);
@ -338,6 +383,8 @@ BlacklistFeatureStatusToGfxFeatureStatus(const nsAString& aStatus)
else if (aStatus == NS_LITERAL_STRING("BLOCKED_OS_VERSION")) else if (aStatus == NS_LITERAL_STRING("BLOCKED_OS_VERSION"))
return nsIGfxInfo::FEATURE_BLOCKED_OS_VERSION; return nsIGfxInfo::FEATURE_BLOCKED_OS_VERSION;
// Do not allow it to set STATUS_UNKNOWN.
return nsIGfxInfo::FEATURE_NO_INFO; return nsIGfxInfo::FEATURE_NO_INFO;
} }
@ -558,12 +605,6 @@ GfxInfoBase::Init()
return NS_OK; return NS_OK;
} }
static const GfxDriverInfo gDriverInfo[] = {
// No combinations that cause a crash on every OS.
GfxDriverInfo()
};
NS_IMETHODIMP NS_IMETHODIMP
GfxInfoBase::GetFeatureStatus(PRInt32 aFeature, PRInt32* aStatus NS_OUTPARAM) GfxInfoBase::GetFeatureStatus(PRInt32 aFeature, PRInt32* aStatus NS_OUTPARAM)
{ {
@ -571,22 +612,145 @@ GfxInfoBase::GetFeatureStatus(PRInt32 aFeature, PRInt32* aStatus NS_OUTPARAM)
return NS_OK; return NS_OK;
nsString version; nsString version;
return GetFeatureStatusImpl(aFeature, aStatus, version); nsTArray<GfxDriverInfo> driverInfo;
return GetFeatureStatusImpl(aFeature, aStatus, version, driverInfo);
}
PRInt32
GfxInfoBase::FindBlocklistedDeviceInList(const nsTArray<GfxDriverInfo>& info,
nsAString& aSuggestedVersion,
PRInt32 aFeature,
OperatingSystem os)
{
PRInt32 status = nsIGfxInfo::FEATURE_STATUS_UNKNOWN;
PRUint32 adapterVendorID = 0;
PRUint32 adapterDeviceID = 0;
nsAutoString adapterDriverVersionString;
if (NS_FAILED(GetAdapterVendorID(&adapterVendorID)) ||
NS_FAILED(GetAdapterDeviceID(&adapterDeviceID)) ||
NS_FAILED(GetAdapterDriverVersion(adapterDriverVersionString)))
{
return NS_OK;
}
PRUint64 driverVersion;
ParseDriverVersion(adapterDriverVersionString, &driverVersion);
PRUint32 i = 0;
for (; i < info.Length(); i++) {
if (info[i].mOperatingSystem != DRIVER_OS_ALL &&
info[i].mOperatingSystem != os)
{
continue;
}
if (info[i].mAdapterVendor != GfxDriverInfo::allAdapterVendors &&
info[i].mAdapterVendor != adapterVendorID) {
continue;
}
if (info[i].mDevices != GfxDriverInfo::allDevices) {
bool deviceMatches = false;
for (const PRUint32 *devices = info[i].mDevices; *devices; ++devices) {
if (*devices == adapterDeviceID) {
deviceMatches = true;
break;
}
}
if (!deviceMatches) {
continue;
}
}
bool match = false;
#if !defined(XP_MACOSX)
switch (info[i].mComparisonOp) {
case DRIVER_LESS_THAN:
match = driverVersion < info[i].mDriverVersion;
break;
case DRIVER_LESS_THAN_OR_EQUAL:
match = driverVersion <= info[i].mDriverVersion;
break;
case DRIVER_GREATER_THAN:
match = driverVersion > info[i].mDriverVersion;
break;
case DRIVER_GREATER_THAN_OR_EQUAL:
match = driverVersion >= info[i].mDriverVersion;
break;
case DRIVER_EQUAL:
match = driverVersion == info[i].mDriverVersion;
break;
case DRIVER_NOT_EQUAL:
match = driverVersion != info[i].mDriverVersion;
break;
case DRIVER_BETWEEN_EXCLUSIVE:
match = driverVersion > info[i].mDriverVersion && driverVersion < info[i].mDriverVersionMax;
break;
case DRIVER_BETWEEN_INCLUSIVE:
match = driverVersion >= info[i].mDriverVersion && driverVersion <= info[i].mDriverVersionMax;
break;
case DRIVER_BETWEEN_INCLUSIVE_START:
match = driverVersion >= info[i].mDriverVersion && driverVersion < info[i].mDriverVersionMax;
break;
default:
NS_WARNING("Bogus op in GfxDriverInfo");
break;
}
#else
// We don't care what driver version it was. We only check OS version and if
// the device matches.
match = true;
#endif
if (match) {
if (info[i].mFeature == GfxDriverInfo::allFeatures ||
info[i].mFeature == aFeature)
{
status = info[i].mFeatureStatus;
break;
}
}
}
// Depends on Windows driver versioning. We don't pass a GfxDriverInfo object
// back to the Windows handler, so we must handle this here.
#if defined(XP_WIN)
if (status == FEATURE_BLOCKED_DRIVER_VERSION) {
if (info[i].mSuggestedVersion) {
aSuggestedVersion.AppendPrintf("%s", info[i].mSuggestedVersion);
} else if (info[i].mComparisonOp == DRIVER_LESS_THAN &&
info[i].mDriverVersion != GfxDriverInfo::allDriverVersions)
{
aSuggestedVersion.AppendPrintf("%lld.%lld.%lld.%lld",
(info[i].mDriverVersion & 0xffff000000000000) >> 48,
(info[i].mDriverVersion & 0x0000ffff00000000) >> 32,
(info[i].mDriverVersion & 0x00000000ffff0000) >> 16,
(info[i].mDriverVersion & 0x000000000000ffff));
}
}
#endif
return status;
} }
nsresult nsresult
GfxInfoBase::GetFeatureStatusImpl(PRInt32 aFeature, GfxInfoBase::GetFeatureStatusImpl(PRInt32 aFeature,
PRInt32* aStatus, PRInt32* aStatus,
nsAString& aVersion, nsAString& aSuggestedVersion,
GfxDriverInfo* aDriverInfo /* = nsnull */, const nsTArray<GfxDriverInfo>& aDriverInfo,
OperatingSystem* aOS /* = nsnull */) OperatingSystem* aOS /* = nsnull */)
{ {
if (*aStatus != nsIGfxInfo::FEATURE_NO_INFO) { if (*aStatus != nsIGfxInfo::FEATURE_STATUS_UNKNOWN) {
// Terminate now with the status determined by the derived type (OS-specific // Terminate now with the status determined by the derived type (OS-specific
// code). // code).
return NS_OK; return NS_OK;
} }
// If an operating system was provided by the derived GetFeatureStatusImpl,
// grab it here. Otherwise, the OS is unknown.
OperatingSystem os = DRIVER_OS_UNKNOWN; OperatingSystem os = DRIVER_OS_UNKNOWN;
if (aOS) if (aOS)
os = *aOS; os = *aOS;
@ -604,137 +768,24 @@ GfxInfoBase::GetFeatureStatusImpl(PRInt32 aFeature,
PRUint64 driverVersion; PRUint64 driverVersion;
ParseDriverVersion(adapterDriverVersionString, &driverVersion); ParseDriverVersion(adapterDriverVersionString, &driverVersion);
// special-case the WinXP test slaves: they have out-of-date drivers, but we still want to // Check if the device is blocked from the downloaded blocklist. If not, check
// whitelist them, actually we do know that this combination of device and driver version // the static list after that. This order is used so that we can later escape
// works well. // out of static blocks (i.e. if we were wrong or something was patched, we
if (os == DRIVER_OS_WINDOWS_XP && // can back out our static block without doing a release).
adapterVendorID == GfxDriverInfo::vendorNVIDIA && InitGfxDriverInfoShutdownObserver();
adapterDeviceID == 0x0861 && // GeForce 9400 if (!mDriverInfo)
driverVersion == V(6,14,11,7756)) mDriverInfo = new nsTArray<GfxDriverInfo>();
{ PRInt32 status = FindBlocklistedDeviceInList(aDriverInfo, aSuggestedVersion, aFeature, os);
return NS_OK; if (status == nsIGfxInfo::FEATURE_STATUS_UNKNOWN) {
status = FindBlocklistedDeviceInList(GetGfxDriverInfo(), aSuggestedVersion, aFeature, os);
} }
PRInt32 status = *aStatus; // It's now done being processed. It's safe to set the status to NO_INFO.
const GfxDriverInfo* info = aDriverInfo ? aDriverInfo : &gDriverInfo[0]; if (status == nsIGfxInfo::FEATURE_STATUS_UNKNOWN) {
// This code will operate in two modes: *aStatus = nsIGfxInfo::FEATURE_NO_INFO;
// It first loops over the driver tuples stored locally in gDriverInfo, } else {
// then loops over it a second time for the OS's specific list to check for *aStatus = status;
// all combinations that can lead to disabling a feature.
bool loopingOverOS = false;
while (true) {
if (!info->mOperatingSystem) {
if (loopingOverOS)
break;
else
{
// Mark us as looping over the OS driver tuples.
loopingOverOS = true;
// Get the GfxDriverInfo table from the OS subclass.
info = GetGfxDriverInfo();
}
}
if (info->mOperatingSystem != DRIVER_OS_ALL &&
info->mOperatingSystem != os)
{
info++;
continue;
}
if (info->mAdapterVendor != GfxDriverInfo::allAdapterVendors &&
info->mAdapterVendor != adapterVendorID) {
info++;
continue;
}
if (info->mDevices != GfxDriverInfo::allDevices) {
bool deviceMatches = false;
for (const PRUint32 *devices = info->mDevices; *devices; ++devices) {
if (*devices == adapterDeviceID) {
deviceMatches = true;
break;
}
}
if (!deviceMatches) {
info++;
continue;
}
}
bool match = false;
#if !defined(XP_MACOSX)
switch (info->mComparisonOp) {
case DRIVER_LESS_THAN:
match = driverVersion < info->mDriverVersion;
break;
case DRIVER_LESS_THAN_OR_EQUAL:
match = driverVersion <= info->mDriverVersion;
break;
case DRIVER_GREATER_THAN:
match = driverVersion > info->mDriverVersion;
break;
case DRIVER_GREATER_THAN_OR_EQUAL:
match = driverVersion >= info->mDriverVersion;
break;
case DRIVER_EQUAL:
match = driverVersion == info->mDriverVersion;
break;
case DRIVER_NOT_EQUAL:
match = driverVersion != info->mDriverVersion;
break;
case DRIVER_BETWEEN_EXCLUSIVE:
match = driverVersion > info->mDriverVersion && driverVersion < info->mDriverVersionMax;
break;
case DRIVER_BETWEEN_INCLUSIVE:
match = driverVersion >= info->mDriverVersion && driverVersion <= info->mDriverVersionMax;
break;
case DRIVER_BETWEEN_INCLUSIVE_START:
match = driverVersion >= info->mDriverVersion && driverVersion < info->mDriverVersionMax;
break;
default:
NS_WARNING("Bogus op in GfxDriverInfo");
break;
}
#else
// We don't care what driver version it was. We only check OS version and if
// the device matches.
match = true;
#endif
if (match) {
if (info->mFeature == GfxDriverInfo::allFeatures ||
info->mFeature == aFeature)
{
status = info->mFeatureStatus;
break;
}
}
info++;
} }
*aStatus = status;
// Depends on Windows driver versioning. We don't pass a GfxDriverInfo object
// back to the Windows handler, so we must handle this here.
#if defined(XP_WIN)
if (status == FEATURE_BLOCKED_DRIVER_VERSION) {
if (info->mSuggestedVersion) {
aVersion.AppendPrintf("%s", info->mSuggestedVersion);
} else if (info->mComparisonOp == DRIVER_LESS_THAN &&
info->mDriverVersion != GfxDriverInfo::allDriverVersions)
{
aVersion.AppendPrintf("%lld.%lld.%lld.%lld",
(info->mDriverVersion & 0xffff000000000000) >> 48,
(info->mDriverVersion & 0x0000ffff00000000) >> 32,
(info->mDriverVersion & 0x00000000ffff0000) >> 16,
(info->mDriverVersion & 0x000000000000ffff));
}
}
#endif
return NS_OK; return NS_OK;
} }
@ -750,7 +801,8 @@ GfxInfoBase::GetFeatureSuggestedDriverVersion(PRInt32 aFeature,
} }
PRInt32 status; PRInt32 status;
return GetFeatureStatusImpl(aFeature, &status, aVersion); nsTArray<GfxDriverInfo> driverInfo;
return GetFeatureStatusImpl(aFeature, &status, aVersion, driverInfo);
} }
@ -776,10 +828,6 @@ GfxInfoBase::EvaluateDownloadedBlacklist(nsTArray<GfxDriverInfo>& aDriverInfo)
0 0
}; };
// GetFeatureStatusImpl wants a zero-GfxDriverInfo terminated array. So, we
// append that to our list.
aDriverInfo.AppendElement(GfxDriverInfo());
// For every feature we know about, we evaluate whether this blacklist has a // For every feature we know about, we evaluate whether this blacklist has a
// non-NO_INFO status. If it does, we set the pref we evaluate in // non-NO_INFO status. If it does, we set the pref we evaluate in
// GetFeatureStatus above, so we don't need to hold on to this blacklist // GetFeatureStatus above, so we don't need to hold on to this blacklist
@ -790,7 +838,7 @@ GfxInfoBase::EvaluateDownloadedBlacklist(nsTArray<GfxDriverInfo>& aDriverInfo)
nsAutoString suggestedVersion; nsAutoString suggestedVersion;
if (NS_SUCCEEDED(GetFeatureStatusImpl(features[i], &status, if (NS_SUCCEEDED(GetFeatureStatusImpl(features[i], &status,
suggestedVersion, suggestedVersion,
aDriverInfo.Elements()))) { aDriverInfo))) {
switch (status) { switch (status) {
default: default:
case nsIGfxInfo::FEATURE_NO_INFO: case nsIGfxInfo::FEATURE_NO_INFO:

View File

@ -87,25 +87,31 @@ public:
// NS_GENERIC_FACTORY_CONSTRUCTOR_INIT require it be nsresult return. // NS_GENERIC_FACTORY_CONSTRUCTOR_INIT require it be nsresult return.
virtual nsresult Init(); virtual nsresult Init();
// Gets the driver info table. Used by GfxInfoBase to check for general cases
// (while subclasses check for more specific ones).
virtual const GfxDriverInfo* GetGfxDriverInfo() = 0;
// only useful on X11 // only useful on X11
NS_IMETHOD_(void) GetData() { } NS_IMETHOD_(void) GetData() { }
static void AddCollector(GfxInfoCollectorBase* collector); static void AddCollector(GfxInfoCollectorBase* collector);
static void RemoveCollector(GfxInfoCollectorBase* collector); static void RemoveCollector(GfxInfoCollectorBase* collector);
static nsTArray<GfxDriverInfo>* mDriverInfo;
static bool mDriverInfoObserverInitialized;
protected: protected:
virtual nsresult GetFeatureStatusImpl(PRInt32 aFeature, PRInt32* aStatus, virtual nsresult GetFeatureStatusImpl(PRInt32 aFeature, PRInt32* aStatus,
nsAString& aSuggestedDriverVersion, nsAString& aSuggestedDriverVersion,
GfxDriverInfo* aDriverInfo = nsnull, const nsTArray<GfxDriverInfo>& aDriverInfo,
OperatingSystem* aOS = nsnull); OperatingSystem* aOS = nsnull);
// Gets the driver info table. Used by GfxInfoBase to check for general cases
// (while subclasses check for more specific ones).
virtual const nsTArray<GfxDriverInfo>& GetGfxDriverInfo() = 0;
private: private:
virtual PRInt32 FindBlocklistedDeviceInList(const nsTArray<GfxDriverInfo>& aDriverInfo,
nsAString& aSuggestedVersion,
PRInt32 aFeature,
OperatingSystem os);
void EvaluateDownloadedBlacklist(nsTArray<GfxDriverInfo>& aDriverInfo); void EvaluateDownloadedBlacklist(nsTArray<GfxDriverInfo>& aDriverInfo);

View File

@ -246,29 +246,30 @@ static inline PRUint64 version(PRUint32 major, PRUint32 minor, PRUint32 revision
return (PRUint64(major) << 32) + (PRUint64(minor) << 16) + PRUint64(revision); return (PRUint64(major) << 32) + (PRUint64(minor) << 16) + PRUint64(revision);
} }
static GfxDriverInfo gDriverInfo[] = { const nsTArray<GfxDriverInfo>&
GfxDriverInfo()
};
const GfxDriverInfo*
GfxInfo::GetGfxDriverInfo() GfxInfo::GetGfxDriverInfo()
{ {
return &gDriverInfo[0]; // Nothing here yet.
//if (!mDriverInfo->Length()) {
//
//}
return *mDriverInfo;
} }
nsresult nsresult
GfxInfo::GetFeatureStatusImpl(PRInt32 aFeature, GfxInfo::GetFeatureStatusImpl(PRInt32 aFeature,
PRInt32 *aStatus, PRInt32 *aStatus,
nsAString & aSuggestedDriverVersion, nsAString & aSuggestedDriverVersion,
GfxDriverInfo* aDriverInfo /* = nsnull */, const nsTArray<GfxDriverInfo>& aDriverInfo,
OperatingSystem* aOS /* = nsnull */) OperatingSystem* aOS /* = nsnull */)
{ {
GetData(); GetData();
*aStatus = nsIGfxInfo::FEATURE_NO_INFO; *aStatus = nsIGfxInfo::FEATURE_STATUS_UNKNOWN;
aSuggestedDriverVersion.SetIsVoid(true); aSuggestedDriverVersion.SetIsVoid(true);
#ifdef MOZ_PLATFORM_MAEMO #ifdef MOZ_PLATFORM_MAEMO
*aStatus = nsIGfxInfo::FEATURE_NO_INFO;
// on Maemo, the glxtest probe doesn't build, and we don't really need GfxInfo anyway // on Maemo, the glxtest probe doesn't build, and we don't really need GfxInfo anyway
return NS_OK; return NS_OK;
#endif #endif
@ -291,6 +292,7 @@ GfxInfo::GetFeatureStatusImpl(PRInt32 aFeature,
!strcmp(mRenderer.get(), "GeForce 9400/PCI/SSE2") && !strcmp(mRenderer.get(), "GeForce 9400/PCI/SSE2") &&
!strcmp(mVersion.get(), "3.2.0 NVIDIA 190.42")) !strcmp(mVersion.get(), "3.2.0 NVIDIA 190.42"))
{ {
*aStatus = nsIGfxInfo::FEATURE_NO_INFO;
return NS_OK; return NS_OK;
} }

View File

@ -84,9 +84,9 @@ protected:
virtual nsresult GetFeatureStatusImpl(PRInt32 aFeature, virtual nsresult GetFeatureStatusImpl(PRInt32 aFeature,
PRInt32 *aStatus, PRInt32 *aStatus,
nsAString & aSuggestedDriverVersion, nsAString & aSuggestedDriverVersion,
GfxDriverInfo* aDriverInfo = nsnull, const nsTArray<GfxDriverInfo>& aDriverInfo,
OperatingSystem* aOS = nsnull); OperatingSystem* aOS = nsnull);
virtual const GfxDriverInfo* GetGfxDriverInfo(); virtual const nsTArray<GfxDriverInfo>& GetGfxDriverInfo();
private: private:
nsCString mVendor; nsCString mVendor;