123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284 |
- /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
- /* 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/. */
- #ifndef __mozilla_widget_GfxDriverInfo_h__
- #define __mozilla_widget_GfxDriverInfo_h__
- #include "nsString.h"
- // Macros for adding a blocklist item to the static list.
- #define APPEND_TO_DRIVER_BLOCKLIST(os, vendor, devices, feature, featureStatus, driverComparator, driverVersion, ruleId, suggestedVersion) \
- mDriverInfo->AppendElement(GfxDriverInfo(os, vendor, devices, feature, featureStatus, driverComparator, driverVersion, ruleId, suggestedVersion))
- #define APPEND_TO_DRIVER_BLOCKLIST2(os, vendor, devices, feature, featureStatus, driverComparator, driverVersion, ruleId) \
- mDriverInfo->AppendElement(GfxDriverInfo(os, vendor, devices, feature, featureStatus, driverComparator, driverVersion, ruleId))
- #define APPEND_TO_DRIVER_BLOCKLIST_RANGE(os, vendor, devices, feature, featureStatus, driverComparator, driverVersion, driverVersionMax, ruleId, suggestedVersion) \
- do { \
- MOZ_ASSERT(driverComparator == DRIVER_BETWEEN_EXCLUSIVE || \
- driverComparator == DRIVER_BETWEEN_INCLUSIVE || \
- driverComparator == DRIVER_BETWEEN_INCLUSIVE_START); \
- GfxDriverInfo info(os, vendor, devices, feature, featureStatus, driverComparator, driverVersion, ruleId, suggestedVersion); \
- info.mDriverVersionMax = driverVersionMax; \
- mDriverInfo->AppendElement(info); \
- } while (false)
- #define APPEND_TO_DRIVER_BLOCKLIST_RANGE_GPU2(os, vendor, devices, feature, featureStatus, driverComparator, driverVersion, driverVersionMax, ruleId, suggestedVersion) \
- do { \
- MOZ_ASSERT(driverComparator == DRIVER_BETWEEN_EXCLUSIVE || \
- driverComparator == DRIVER_BETWEEN_INCLUSIVE || \
- driverComparator == DRIVER_BETWEEN_INCLUSIVE_START); \
- GfxDriverInfo info(os, vendor, devices, feature, featureStatus, driverComparator, driverVersion, ruleId, suggestedVersion, false, true); \
- info.mDriverVersionMax = driverVersionMax; \
- mDriverInfo->AppendElement(info); \
- } while (false)
- namespace mozilla {
- namespace widget {
- enum class OperatingSystem {
- Unknown,
- Windows,
- WindowsXP,
- WindowsServer2003,
- WindowsVista,
- Windows7,
- Windows8,
- Windows8_1,
- Windows10,
- Linux,
- };
- enum VersionComparisonOp {
- DRIVER_LESS_THAN, // driver < version
- DRIVER_BUILD_ID_LESS_THAN, // driver build id < version
- DRIVER_LESS_THAN_OR_EQUAL, // driver <= version
- DRIVER_BUILD_ID_LESS_THAN_OR_EQUAL, // driver build id <= version
- 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
- DRIVER_COMPARISON_IGNORED
- };
- enum DeviceFamily {
- IntelGMA500,
- IntelGMA900,
- IntelGMA950,
- IntelGMA3150,
- IntelGMAX3000,
- IntelGMAX4500HD,
- IntelHDGraphicsToSandyBridge,
- IntelHD3000,
- IntelMobileHDGraphics,
- NvidiaBlockD3D9Layers,
- RadeonX1000,
- Geforce7300GT,
- Nvidia310M,
- Nvidia8800GTS,
- Bug1137716,
- Bug1116812,
- Bug1155608,
- Bug1207665,
- DeviceFamilyMax
- };
- enum DeviceVendor {
- VendorAll,
- VendorIntel,
- VendorNVIDIA,
- VendorAMD,
- VendorATI,
- VendorMicrosoft,
- DeviceVendorMax
- };
- /* Array of devices to match, or an empty array for all devices */
- typedef nsTArray<nsString> GfxDeviceFamily;
- struct GfxDriverInfo
- {
- // If |ownDevices| is true, you are transferring ownership of the devices
- // array, and it will be deleted when this GfxDriverInfo is destroyed.
- GfxDriverInfo(OperatingSystem os, nsAString& vendor, GfxDeviceFamily* devices,
- int32_t feature, int32_t featureStatus, VersionComparisonOp op,
- uint64_t driverVersion, const char *ruleId,
- const char *suggestedVersion = nullptr,
- bool ownDevices = false, bool gpu2 = false);
- GfxDriverInfo();
- GfxDriverInfo(const GfxDriverInfo&);
- ~GfxDriverInfo();
- OperatingSystem mOperatingSystem;
- uint32_t mOperatingSystemVersion;
- nsString mAdapterVendor;
- static GfxDeviceFamily* const allDevices;
- GfxDeviceFamily* mDevices;
- // Whether the mDevices array should be deleted when this structure is
- // deallocated. False by default.
- bool mDeleteDevices;
- /* A feature from nsIGfxInfo, or all features */
- int32_t mFeature;
- static int32_t allFeatures;
- /* A feature status from nsIGfxInfo */
- int32_t mFeatureStatus;
- VersionComparisonOp mComparisonOp;
- /* versions are assumed to be A.B.C.D packed as 0xAAAABBBBCCCCDDDD */
- uint64_t mDriverVersion;
- uint64_t mDriverVersionMax;
- static uint64_t allDriverVersions;
- const char *mSuggestedVersion;
- nsCString mRuleId;
- static const GfxDeviceFamily* GetDeviceFamily(DeviceFamily id);
- static GfxDeviceFamily* mDeviceFamilies[DeviceFamilyMax];
- static const nsAString& GetDeviceVendor(DeviceVendor id);
- static nsAString* mDeviceVendors[DeviceVendorMax];
- nsString mModel, mHardware, mProduct, mManufacturer;
- bool mGpu2;
- };
- #define GFX_DRIVER_VERSION(a,b,c,d) \
- ((uint64_t(a)<<48) | (uint64_t(b)<<32) | (uint64_t(c)<<16) | uint64_t(d))
- 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.
- inline bool SplitDriverVersion(const char *aSource, char *aAStr, char *aBStr, char *aCStr, char *aDStr)
- {
- // sscanf doesn't do what we want here to we parse this manually.
- int len = strlen(aSource);
- // This "4" is hardcoded in a few places, including once as a 3.
- char *dest[4] = { aAStr, aBStr, aCStr, aDStr };
- unsigned destIdx = 0;
- unsigned destPos = 0;
- for (int i = 0; i < len; i++) {
- if (destIdx >= 4) {
- // Invalid format found. Ensure we don't access dest beyond bounds.
- return false;
- }
- if (aSource[i] == '.') {
- MOZ_ASSERT (destIdx < 4 && destPos <= 4);
- 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;
- }
- MOZ_ASSERT (destIdx < 4 && destPos < 4);
- dest[destIdx][destPos++] = aSource[i];
- }
- // Take care of the trailing period
- if (destIdx >= 4) {
- return false;
- }
- // Add last terminator.
- MOZ_ASSERT (destIdx < 4 && destPos <= 4);
- dest[destIdx][destPos] = 0;
- if (destIdx != 3) {
- return false;
- }
- return true;
- }
- // This allows us to pad driver version 'substrings' with 0s, this
- // 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.
- inline void PadDriverDecimal(char *aString)
- {
- for (int i = 0; i < 4; i++) {
- if (!aString[i]) {
- for (int c = i; c < 4; c++) {
- aString[c] = '0';
- }
- break;
- }
- }
- aString[4] = 0;
- }
- inline bool
- ParseDriverVersion(const nsAString& aVersion, uint64_t *aNumericVersion)
- {
- *aNumericVersion = 0;
- #if defined(XP_WIN)
- int a, b, c, d;
- char aStr[8], bStr[8], cStr[8], dStr[8];
- /* honestly, why do I even bother */
- if (!SplitDriverVersion(NS_LossyConvertUTF16toASCII(aVersion).get(), aStr, bStr, cStr, dStr))
- return false;
- PadDriverDecimal(bStr);
- PadDriverDecimal(cStr);
- PadDriverDecimal(dStr);
- a = atoi(aStr);
- b = atoi(bStr);
- c = atoi(cStr);
- d = atoi(dStr);
- 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);
- MOZ_ASSERT(*aNumericVersion != GfxDriverInfo::allDriverVersions);
- return true;
- #else
- return false;
- #endif
- }
- } // namespace widget
- } // namespace mozilla
- #endif /*__mozilla_widget_GfxDriverInfo_h__ */
|