2011-01-20 04:21:07 +03:00
|
|
|
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
2012-05-21 15:12:37 +04:00
|
|
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
|
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
2011-01-20 04:21:07 +03:00
|
|
|
|
|
|
|
#ifndef __mozilla_widget_GfxDriverInfo_h__
|
|
|
|
#define __mozilla_widget_GfxDriverInfo_h__
|
|
|
|
|
2013-03-17 11:55:16 +04:00
|
|
|
#include "nsString.h"
|
|
|
|
|
2011-12-15 09:03:01 +04:00
|
|
|
// Macros for adding a blocklist item to the static list.
|
2016-04-14 00:12:47 +03:00
|
|
|
#define APPEND_TO_DRIVER_BLOCKLIST(os, vendor, devices, feature, \
|
|
|
|
featureStatus, driverComparator, \
|
2018-05-14 18:16:50 +03:00
|
|
|
driverVersion, ruleId, suggestedVersion) \
|
|
|
|
sDriverInfo->AppendElement(GfxDriverInfo( \
|
|
|
|
os, vendor, devices, feature, featureStatus, driverComparator, \
|
2016-04-14 00:12:47 +03:00
|
|
|
driverVersion, ruleId, suggestedVersion))
|
|
|
|
#define APPEND_TO_DRIVER_BLOCKLIST2(os, vendor, devices, feature, \
|
2018-05-14 18:16:50 +03:00
|
|
|
featureStatus, driverComparator, \
|
|
|
|
driverVersion, ruleId) \
|
|
|
|
sDriverInfo->AppendElement(GfxDriverInfo(os, vendor, devices, feature, \
|
2016-04-14 00:12:47 +03:00
|
|
|
featureStatus, driverComparator, \
|
|
|
|
driverVersion, ruleId))
|
2018-11-30 13:46:48 +03:00
|
|
|
|
2016-04-14 00:12:47 +03:00
|
|
|
#define APPEND_TO_DRIVER_BLOCKLIST_RANGE( \
|
|
|
|
os, vendor, devices, feature, featureStatus, driverComparator, \
|
|
|
|
driverVersion, driverVersionMax, ruleId, suggestedVersion) \
|
2013-03-20 04:44:10 +04:00
|
|
|
do { \
|
|
|
|
MOZ_ASSERT(driverComparator == DRIVER_BETWEEN_EXCLUSIVE || \
|
|
|
|
driverComparator == DRIVER_BETWEEN_INCLUSIVE || \
|
|
|
|
driverComparator == DRIVER_BETWEEN_INCLUSIVE_START); \
|
2016-04-14 00:12:47 +03:00
|
|
|
GfxDriverInfo info(os, vendor, devices, feature, featureStatus, \
|
|
|
|
driverComparator, driverVersion, ruleId, \
|
|
|
|
suggestedVersion); \
|
2013-03-20 04:44:10 +04:00
|
|
|
info.mDriverVersionMax = driverVersionMax; \
|
2018-05-14 18:16:50 +03:00
|
|
|
sDriverInfo->AppendElement(info); \
|
2013-03-20 04:44:10 +04:00
|
|
|
} while (false)
|
2018-11-30 13:46:48 +03:00
|
|
|
|
2016-04-14 00:12:47 +03:00
|
|
|
#define APPEND_TO_DRIVER_BLOCKLIST_RANGE_GPU2( \
|
|
|
|
os, vendor, devices, feature, featureStatus, driverComparator, \
|
|
|
|
driverVersion, driverVersionMax, ruleId, suggestedVersion) \
|
2015-03-21 22:37:00 +03:00
|
|
|
do { \
|
|
|
|
MOZ_ASSERT(driverComparator == DRIVER_BETWEEN_EXCLUSIVE || \
|
|
|
|
driverComparator == DRIVER_BETWEEN_INCLUSIVE || \
|
|
|
|
driverComparator == DRIVER_BETWEEN_INCLUSIVE_START); \
|
2016-04-14 00:12:47 +03:00
|
|
|
GfxDriverInfo info(os, vendor, devices, feature, featureStatus, \
|
|
|
|
driverComparator, driverVersion, ruleId, \
|
|
|
|
suggestedVersion, false, true); \
|
2015-03-21 22:37:00 +03:00
|
|
|
info.mDriverVersionMax = driverVersionMax; \
|
2018-05-14 18:16:50 +03:00
|
|
|
sDriverInfo->AppendElement(info); \
|
2015-03-21 22:37:00 +03:00
|
|
|
} while (false)
|
|
|
|
|
2011-01-20 04:21:07 +03:00
|
|
|
namespace mozilla {
|
|
|
|
namespace widget {
|
|
|
|
|
2016-06-03 23:13:08 +03:00
|
|
|
enum class OperatingSystem {
|
|
|
|
Unknown,
|
|
|
|
Windows,
|
|
|
|
WindowsXP,
|
|
|
|
WindowsServer2003,
|
|
|
|
WindowsVista,
|
|
|
|
Windows7,
|
|
|
|
Windows8,
|
|
|
|
Windows8_1,
|
|
|
|
Windows10,
|
|
|
|
Linux,
|
|
|
|
OSX,
|
|
|
|
OSX10_5,
|
|
|
|
OSX10_6,
|
|
|
|
OSX10_7,
|
|
|
|
OSX10_8,
|
|
|
|
OSX10_9,
|
|
|
|
OSX10_10,
|
|
|
|
OSX10_11,
|
2016-07-05 00:25:25 +03:00
|
|
|
OSX10_12,
|
2017-09-28 17:21:10 +03:00
|
|
|
OSX10_13,
|
2016-06-03 23:13:08 +03:00
|
|
|
Android,
|
|
|
|
Ios
|
2011-01-20 04:21:07 +03:00
|
|
|
};
|
|
|
|
|
|
|
|
enum VersionComparisonOp {
|
|
|
|
DRIVER_LESS_THAN, // driver < version
|
2016-08-08 09:35:00 +03:00
|
|
|
DRIVER_BUILD_ID_LESS_THAN, // driver build id < version
|
2011-01-20 04:21:07 +03:00
|
|
|
DRIVER_LESS_THAN_OR_EQUAL, // driver <= version
|
2016-08-31 20:59:00 +03:00
|
|
|
DRIVER_BUILD_ID_LESS_THAN_OR_EQUAL, // driver build id <= version
|
2011-01-20 04:21:07 +03:00
|
|
|
DRIVER_GREATER_THAN, // driver > version
|
|
|
|
DRIVER_GREATER_THAN_OR_EQUAL, // driver >= version
|
|
|
|
DRIVER_EQUAL, // driver == version
|
|
|
|
DRIVER_NOT_EQUAL, // driver != version
|
|
|
|
DRIVER_BETWEEN_EXCLUSIVE, // driver > version && driver < versionMax
|
|
|
|
DRIVER_BETWEEN_INCLUSIVE, // driver >= version && driver <= versionMax
|
|
|
|
DRIVER_BETWEEN_INCLUSIVE_START, // driver >= version && driver < versionMax
|
2012-05-04 23:33:59 +04:00
|
|
|
DRIVER_COMPARISON_IGNORED
|
2011-01-20 04:21:07 +03:00
|
|
|
};
|
|
|
|
|
2011-12-15 09:02:59 +04:00
|
|
|
enum DeviceFamily {
|
|
|
|
IntelGMA500,
|
|
|
|
IntelGMA900,
|
|
|
|
IntelGMA950,
|
|
|
|
IntelGMA3150,
|
|
|
|
IntelGMAX3000,
|
|
|
|
IntelGMAX4500HD,
|
2016-04-09 06:18:03 +03:00
|
|
|
IntelHDGraphicsToSandyBridge,
|
2018-03-22 09:33:52 +03:00
|
|
|
IntelHDGraphicsToHaswell,
|
2014-08-01 09:59:36 +04:00
|
|
|
IntelHD3000,
|
2013-03-12 23:40:29 +04:00
|
|
|
IntelMobileHDGraphics,
|
2011-12-15 09:03:01 +04:00
|
|
|
NvidiaBlockD3D9Layers,
|
2011-12-15 09:03:06 +04:00
|
|
|
RadeonX1000,
|
|
|
|
Geforce7300GT,
|
2014-08-13 08:25:13 +04:00
|
|
|
Nvidia310M,
|
2015-04-17 03:41:37 +03:00
|
|
|
Nvidia8800GTS,
|
2015-03-21 22:37:00 +03:00
|
|
|
Bug1137716,
|
2015-03-26 02:58:48 +03:00
|
|
|
Bug1116812,
|
2015-04-30 00:49:49 +03:00
|
|
|
Bug1155608,
|
2015-09-28 02:44:00 +03:00
|
|
|
Bug1207665,
|
2018-04-13 15:06:52 +03:00
|
|
|
Bug1447141,
|
2018-10-24 21:58:00 +03:00
|
|
|
NvidiaBlockWebRender,
|
2011-12-15 09:03:01 +04:00
|
|
|
DeviceFamilyMax
|
2011-11-03 18:50:40 +04:00
|
|
|
};
|
|
|
|
|
2011-12-15 09:03:01 +04:00
|
|
|
enum DeviceVendor {
|
2018-01-08 19:35:48 +03:00
|
|
|
VendorAll, // There is an assumption that this is the first enum
|
2011-12-15 09:03:01 +04:00
|
|
|
VendorIntel,
|
|
|
|
VendorNVIDIA,
|
|
|
|
VendorAMD,
|
|
|
|
VendorATI,
|
2013-06-14 23:34:41 +04:00
|
|
|
VendorMicrosoft,
|
2018-01-08 19:35:48 +03:00
|
|
|
VendorParallels,
|
2018-01-06 04:28:02 +03:00
|
|
|
VendorQualcomm,
|
2019-02-08 22:36:08 +03:00
|
|
|
|
|
|
|
// Wildcard for all Mesa drivers.
|
|
|
|
VendorMesaAll,
|
|
|
|
// Note that the following list of Mesa drivers is not comprehensive; we pull
|
|
|
|
// the DRI driver at runtime. These drivers are provided for convenience when
|
|
|
|
// populating the local blocklist.
|
|
|
|
VendorMesaLLVMPipe,
|
|
|
|
VendorMesaSoftPipe,
|
|
|
|
VendorMesaSWRast,
|
|
|
|
// A generic ID to be provided when we can't determine the DRI driver on Mesa.
|
|
|
|
VendorMesaUnknown,
|
|
|
|
|
2011-12-15 09:03:01 +04:00
|
|
|
DeviceVendorMax
|
|
|
|
};
|
|
|
|
|
|
|
|
/* Array of devices to match, or an empty array for all devices */
|
|
|
|
typedef nsTArray<nsString> GfxDeviceFamily;
|
2011-01-20 04:21:07 +03:00
|
|
|
|
|
|
|
struct GfxDriverInfo {
|
2011-01-20 04:33:51 +03:00
|
|
|
// If |ownDevices| is true, you are transferring ownership of the devices
|
|
|
|
// array, and it will be deleted when this GfxDriverInfo is destroyed.
|
2011-12-15 09:03:01 +04:00
|
|
|
GfxDriverInfo(OperatingSystem os, nsAString &vendor, GfxDeviceFamily *devices,
|
2012-08-22 19:56:38 +04:00
|
|
|
int32_t feature, int32_t featureStatus, VersionComparisonOp op,
|
2016-04-14 00:12:47 +03:00
|
|
|
uint64_t driverVersion, const char *ruleId,
|
|
|
|
const char *suggestedVersion = nullptr, bool ownDevices = false,
|
2015-03-21 22:37:00 +03:00
|
|
|
bool gpu2 = false);
|
2011-01-20 04:33:51 +03:00
|
|
|
|
|
|
|
GfxDriverInfo();
|
|
|
|
GfxDriverInfo(const GfxDriverInfo &);
|
|
|
|
~GfxDriverInfo();
|
|
|
|
|
2011-01-20 04:21:07 +03:00
|
|
|
OperatingSystem mOperatingSystem;
|
2012-11-02 01:13:10 +04:00
|
|
|
uint32_t mOperatingSystemVersion;
|
2011-01-20 04:21:07 +03:00
|
|
|
|
2011-12-15 09:03:01 +04:00
|
|
|
nsString mAdapterVendor;
|
2011-01-20 04:21:07 +03:00
|
|
|
|
2011-12-15 09:03:01 +04:00
|
|
|
static GfxDeviceFamily *const allDevices;
|
|
|
|
GfxDeviceFamily *mDevices;
|
2011-01-20 04:21:07 +03:00
|
|
|
|
2011-01-20 04:33:51 +03:00
|
|
|
// Whether the mDevices array should be deleted when this structure is
|
|
|
|
// deallocated. False by default.
|
|
|
|
bool mDeleteDevices;
|
|
|
|
|
2011-01-20 04:21:07 +03:00
|
|
|
/* A feature from nsIGfxInfo, or all features */
|
2012-08-22 19:56:38 +04:00
|
|
|
int32_t mFeature;
|
|
|
|
static int32_t allFeatures;
|
2011-01-20 04:21:07 +03:00
|
|
|
|
|
|
|
/* A feature status from nsIGfxInfo */
|
2012-08-22 19:56:38 +04:00
|
|
|
int32_t mFeatureStatus;
|
2011-01-20 04:21:07 +03:00
|
|
|
|
|
|
|
VersionComparisonOp mComparisonOp;
|
|
|
|
|
|
|
|
/* versions are assumed to be A.B.C.D packed as 0xAAAABBBBCCCCDDDD */
|
2012-08-22 19:56:38 +04:00
|
|
|
uint64_t mDriverVersion;
|
|
|
|
uint64_t mDriverVersionMax;
|
|
|
|
static uint64_t allDriverVersions;
|
2011-11-03 18:50:40 +04:00
|
|
|
|
2011-01-29 05:12:25 +03:00
|
|
|
const char *mSuggestedVersion;
|
2016-04-14 00:12:47 +03:00
|
|
|
nsCString mRuleId;
|
2011-12-15 09:02:59 +04:00
|
|
|
|
2011-12-15 09:03:01 +04:00
|
|
|
static const GfxDeviceFamily *GetDeviceFamily(DeviceFamily id);
|
2018-05-14 18:16:50 +03:00
|
|
|
static GfxDeviceFamily *sDeviceFamilies[DeviceFamilyMax];
|
2011-12-15 09:03:01 +04:00
|
|
|
|
|
|
|
static const nsAString &GetDeviceVendor(DeviceVendor id);
|
2018-05-14 18:16:50 +03:00
|
|
|
static nsAString *sDeviceVendors[DeviceVendorMax];
|
2012-11-02 01:13:10 +04:00
|
|
|
|
|
|
|
nsString mModel, mHardware, mProduct, mManufacturer;
|
2015-03-21 22:37:00 +03:00
|
|
|
|
|
|
|
bool mGpu2;
|
2011-01-20 04:21:07 +03:00
|
|
|
};
|
|
|
|
|
|
|
|
#define GFX_DRIVER_VERSION(a, b, c, d) \
|
2012-08-22 19:56:38 +04:00
|
|
|
((uint64_t(a) << 48) | (uint64_t(b) << 32) | (uint64_t(c) << 16) | \
|
|
|
|
uint64_t(d))
|
2011-01-20 04:21:07 +03:00
|
|
|
|
2012-09-18 00:50:38 +04:00
|
|
|
inline uint64_t V(uint32_t a, uint32_t b, uint32_t c, uint32_t d) {
|
|
|
|
// We make sure every driver number is padded by 0s, this will allow us the
|
|
|
|
// easiest 'compare as if decimals' approach. See ParseDriverVersion for a
|
|
|
|
// more extensive explanation of this approach.
|
|
|
|
while (b > 0 && b < 1000) {
|
|
|
|
b *= 10;
|
|
|
|
}
|
|
|
|
while (c > 0 && c < 1000) {
|
|
|
|
c *= 10;
|
|
|
|
}
|
|
|
|
while (d > 0 && d < 1000) {
|
|
|
|
d *= 10;
|
|
|
|
}
|
|
|
|
return GFX_DRIVER_VERSION(a, b, c, d);
|
|
|
|
}
|
|
|
|
|
|
|
|
// All destination string storage needs to have at least 5 bytes available.
|
2012-12-05 08:51:52 +04:00
|
|
|
inline bool SplitDriverVersion(const char *aSource, char *aAStr, char *aBStr,
|
|
|
|
char *aCStr, char *aDStr) {
|
2012-09-18 00:50:38 +04:00
|
|
|
// sscanf doesn't do what we want here to we parse this manually.
|
|
|
|
int len = strlen(aSource);
|
2015-08-20 01:14:59 +03:00
|
|
|
|
|
|
|
// This "4" is hardcoded in a few places, including once as a 3.
|
2012-09-18 00:50:38 +04:00
|
|
|
char *dest[4] = {aAStr, aBStr, aCStr, aDStr};
|
2012-12-22 21:29:04 +04:00
|
|
|
unsigned destIdx = 0;
|
|
|
|
unsigned destPos = 0;
|
2012-09-18 00:50:38 +04:00
|
|
|
|
|
|
|
for (int i = 0; i < len; i++) {
|
2015-08-20 01:14:59 +03:00
|
|
|
if (destIdx >= 4) {
|
2012-09-18 00:50:38 +04:00
|
|
|
// Invalid format found. Ensure we don't access dest beyond bounds.
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (aSource[i] == '.') {
|
2015-08-20 01:14:59 +03:00
|
|
|
MOZ_ASSERT(destIdx < 4 && destPos <= 4);
|
2012-09-18 00:50:38 +04:00
|
|
|
dest[destIdx++][destPos] = 0;
|
|
|
|
destPos = 0;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (destPos > 3) {
|
|
|
|
// Ignore more than 4 chars. Ensure we never access dest[destIdx]
|
|
|
|
// beyond its bounds.
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2015-08-20 01:14:59 +03:00
|
|
|
MOZ_ASSERT(destIdx < 4 && destPos < 4);
|
2012-09-18 00:50:38 +04:00
|
|
|
dest[destIdx][destPos++] = aSource[i];
|
|
|
|
}
|
|
|
|
|
2015-08-20 01:14:59 +03:00
|
|
|
// Take care of the trailing period
|
|
|
|
if (destIdx >= 4) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2012-09-18 00:50:38 +04:00
|
|
|
// Add last terminator.
|
2015-08-20 01:14:59 +03:00
|
|
|
MOZ_ASSERT(destIdx < 4 && destPos <= 4);
|
2012-09-18 00:50:38 +04:00
|
|
|
dest[destIdx][destPos] = 0;
|
|
|
|
|
2015-08-20 01:14:59 +03:00
|
|
|
if (destIdx != 3) {
|
2012-09-18 00:50:38 +04:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2012-12-05 08:51:52 +04:00
|
|
|
// This allows us to pad driver version 'substrings' with 0s, this
|
2012-09-18 00:50:38 +04:00
|
|
|
// effectively allows us to treat the version numbers as 'decimals'. This is
|
|
|
|
// a little strange but this method seems to do the right thing for all
|
|
|
|
// different vendor's driver strings. i.e. .98 will become 9800, which is
|
|
|
|
// larger than .978 which would become 9780.
|
2012-12-05 08:51:52 +04:00
|
|
|
inline void PadDriverDecimal(char *aString) {
|
2012-09-18 00:50:38 +04:00
|
|
|
for (int i = 0; i < 4; i++) {
|
|
|
|
if (!aString[i]) {
|
|
|
|
for (int c = i; c < 4; c++) {
|
|
|
|
aString[c] = '0';
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
aString[4] = 0;
|
|
|
|
}
|
|
|
|
|
2013-08-06 06:00:42 +04:00
|
|
|
inline bool ParseDriverVersion(const nsAString &aVersion,
|
|
|
|
uint64_t *aNumericVersion) {
|
2014-05-06 10:38:24 +04:00
|
|
|
*aNumericVersion = 0;
|
|
|
|
|
2019-02-08 22:36:08 +03:00
|
|
|
#if defined(XP_WIN) || defined(MOZ_X11)
|
2011-01-20 04:21:07 +03:00
|
|
|
int a, b, c, d;
|
2012-09-18 00:50:38 +04:00
|
|
|
char aStr[8], bStr[8], cStr[8], dStr[8];
|
2011-01-20 04:21:07 +03:00
|
|
|
/* honestly, why do I even bother */
|
2012-09-18 00:50:38 +04:00
|
|
|
if (!SplitDriverVersion(NS_LossyConvertUTF16toASCII(aVersion).get(), aStr,
|
|
|
|
bStr, cStr, dStr))
|
2011-01-20 04:21:07 +03:00
|
|
|
return false;
|
2012-09-18 00:50:38 +04:00
|
|
|
|
|
|
|
PadDriverDecimal(bStr);
|
|
|
|
PadDriverDecimal(cStr);
|
|
|
|
PadDriverDecimal(dStr);
|
|
|
|
|
|
|
|
a = atoi(aStr);
|
|
|
|
b = atoi(bStr);
|
|
|
|
c = atoi(cStr);
|
|
|
|
d = atoi(dStr);
|
|
|
|
|
2011-01-20 04:21:07 +03:00
|
|
|
if (a < 0 || a > 0xffff) return false;
|
|
|
|
if (b < 0 || b > 0xffff) return false;
|
|
|
|
if (c < 0 || c > 0xffff) return false;
|
|
|
|
if (d < 0 || d > 0xffff) return false;
|
|
|
|
|
|
|
|
*aNumericVersion = GFX_DRIVER_VERSION(a, b, c, d);
|
2016-06-03 23:13:08 +03:00
|
|
|
MOZ_ASSERT(*aNumericVersion != GfxDriverInfo::allDriverVersions);
|
2014-05-06 10:38:24 +04:00
|
|
|
return true;
|
2011-12-15 09:03:03 +04:00
|
|
|
#elif defined(ANDROID)
|
|
|
|
// Can't use aVersion.ToInteger() because that's not compiled into our code
|
|
|
|
// unless we have XPCOM_GLUE_AVOID_NSPR disabled.
|
|
|
|
*aNumericVersion = atoi(NS_LossyConvertUTF16toASCII(aVersion).get());
|
2016-06-03 23:13:08 +03:00
|
|
|
MOZ_ASSERT(*aNumericVersion != GfxDriverInfo::allDriverVersions);
|
2011-01-20 04:21:07 +03:00
|
|
|
return true;
|
2014-05-06 10:38:24 +04:00
|
|
|
#else
|
|
|
|
return false;
|
|
|
|
#endif
|
2011-01-20 04:21:07 +03:00
|
|
|
}
|
|
|
|
|
2015-07-13 18:25:42 +03:00
|
|
|
} // namespace widget
|
|
|
|
} // namespace mozilla
|
2011-01-20 04:21:07 +03:00
|
|
|
|
|
|
|
#endif /*__mozilla_widget_GfxDriverInfo_h__ */
|