widget/xpwidgets/GfxDriverInfo.h

Thu, 22 Jan 2015 13:21:57 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 22 Jan 2015 13:21:57 +0100
branch
TOR_BUG_9701
changeset 15
b8a032363ba2
permissions
-rw-r--r--

Incorporate requested changes from Mozilla in review:
https://bugzilla.mozilla.org/show_bug.cgi?id=1123480#c6

michael@0 1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
michael@0 2 /* This Source Code Form is subject to the terms of the Mozilla Public
michael@0 3 * License, v. 2.0. If a copy of the MPL was not distributed with this
michael@0 4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
michael@0 5
michael@0 6 #ifndef __mozilla_widget_GfxDriverInfo_h__
michael@0 7 #define __mozilla_widget_GfxDriverInfo_h__
michael@0 8
michael@0 9 #include "mozilla/ArrayUtils.h" // ArrayLength
michael@0 10 #include "nsString.h"
michael@0 11
michael@0 12 // Macros for adding a blocklist item to the static list.
michael@0 13 #define APPEND_TO_DRIVER_BLOCKLIST(os, vendor, devices, feature, featureStatus, driverComparator, driverVersion, suggestedVersion) \
michael@0 14 mDriverInfo->AppendElement(GfxDriverInfo(os, vendor, devices, feature, featureStatus, driverComparator, driverVersion, suggestedVersion))
michael@0 15 #define APPEND_TO_DRIVER_BLOCKLIST2(os, vendor, devices, feature, featureStatus, driverComparator, driverVersion) \
michael@0 16 mDriverInfo->AppendElement(GfxDriverInfo(os, vendor, devices, feature, featureStatus, driverComparator, driverVersion))
michael@0 17
michael@0 18 #define APPEND_TO_DRIVER_BLOCKLIST_RANGE(os, vendor, devices, feature, featureStatus, driverComparator, driverVersion, driverVersionMax, suggestedVersion) \
michael@0 19 do { \
michael@0 20 MOZ_ASSERT(driverComparator == DRIVER_BETWEEN_EXCLUSIVE || \
michael@0 21 driverComparator == DRIVER_BETWEEN_INCLUSIVE || \
michael@0 22 driverComparator == DRIVER_BETWEEN_INCLUSIVE_START); \
michael@0 23 GfxDriverInfo info(os, vendor, devices, feature, featureStatus, driverComparator, driverVersion, suggestedVersion); \
michael@0 24 info.mDriverVersionMax = driverVersionMax; \
michael@0 25 mDriverInfo->AppendElement(info); \
michael@0 26 } while (false)
michael@0 27
michael@0 28 namespace mozilla {
michael@0 29 namespace widget {
michael@0 30
michael@0 31 enum OperatingSystem {
michael@0 32 DRIVER_OS_UNKNOWN = 0,
michael@0 33 DRIVER_OS_WINDOWS_XP,
michael@0 34 DRIVER_OS_WINDOWS_SERVER_2003,
michael@0 35 DRIVER_OS_WINDOWS_VISTA,
michael@0 36 DRIVER_OS_WINDOWS_7,
michael@0 37 DRIVER_OS_WINDOWS_8,
michael@0 38 DRIVER_OS_WINDOWS_8_1,
michael@0 39 DRIVER_OS_LINUX,
michael@0 40 DRIVER_OS_OS_X_10_5,
michael@0 41 DRIVER_OS_OS_X_10_6,
michael@0 42 DRIVER_OS_OS_X_10_7,
michael@0 43 DRIVER_OS_OS_X_10_8,
michael@0 44 DRIVER_OS_ANDROID,
michael@0 45 DRIVER_OS_ALL
michael@0 46 };
michael@0 47
michael@0 48 enum VersionComparisonOp {
michael@0 49 DRIVER_LESS_THAN, // driver < version
michael@0 50 DRIVER_LESS_THAN_OR_EQUAL, // driver <= version
michael@0 51 DRIVER_GREATER_THAN, // driver > version
michael@0 52 DRIVER_GREATER_THAN_OR_EQUAL, // driver >= version
michael@0 53 DRIVER_EQUAL, // driver == version
michael@0 54 DRIVER_NOT_EQUAL, // driver != version
michael@0 55 DRIVER_BETWEEN_EXCLUSIVE, // driver > version && driver < versionMax
michael@0 56 DRIVER_BETWEEN_INCLUSIVE, // driver >= version && driver <= versionMax
michael@0 57 DRIVER_BETWEEN_INCLUSIVE_START, // driver >= version && driver < versionMax
michael@0 58 DRIVER_COMPARISON_IGNORED
michael@0 59 };
michael@0 60
michael@0 61 enum DeviceFamily {
michael@0 62 IntelGMA500,
michael@0 63 IntelGMA900,
michael@0 64 IntelGMA950,
michael@0 65 IntelGMA3150,
michael@0 66 IntelGMAX3000,
michael@0 67 IntelGMAX4500HD,
michael@0 68 IntelMobileHDGraphics,
michael@0 69 NvidiaBlockD3D9Layers,
michael@0 70 RadeonX1000,
michael@0 71 Geforce7300GT,
michael@0 72 DeviceFamilyMax
michael@0 73 };
michael@0 74
michael@0 75 enum DeviceVendor {
michael@0 76 VendorAll,
michael@0 77 VendorIntel,
michael@0 78 VendorNVIDIA,
michael@0 79 VendorAMD,
michael@0 80 VendorATI,
michael@0 81 VendorMicrosoft,
michael@0 82 DeviceVendorMax
michael@0 83 };
michael@0 84
michael@0 85 /* Array of devices to match, or an empty array for all devices */
michael@0 86 typedef nsTArray<nsString> GfxDeviceFamily;
michael@0 87
michael@0 88 struct GfxDriverInfo
michael@0 89 {
michael@0 90 // If |ownDevices| is true, you are transferring ownership of the devices
michael@0 91 // array, and it will be deleted when this GfxDriverInfo is destroyed.
michael@0 92 GfxDriverInfo(OperatingSystem os, nsAString& vendor, GfxDeviceFamily* devices,
michael@0 93 int32_t feature, int32_t featureStatus, VersionComparisonOp op,
michael@0 94 uint64_t driverVersion, const char *suggestedVersion = nullptr,
michael@0 95 bool ownDevices = false);
michael@0 96
michael@0 97 GfxDriverInfo();
michael@0 98 GfxDriverInfo(const GfxDriverInfo&);
michael@0 99 ~GfxDriverInfo();
michael@0 100
michael@0 101 OperatingSystem mOperatingSystem;
michael@0 102 uint32_t mOperatingSystemVersion;
michael@0 103
michael@0 104 nsString mAdapterVendor;
michael@0 105
michael@0 106 static GfxDeviceFamily* const allDevices;
michael@0 107 GfxDeviceFamily* mDevices;
michael@0 108
michael@0 109 // Whether the mDevices array should be deleted when this structure is
michael@0 110 // deallocated. False by default.
michael@0 111 bool mDeleteDevices;
michael@0 112
michael@0 113 /* A feature from nsIGfxInfo, or all features */
michael@0 114 int32_t mFeature;
michael@0 115 static int32_t allFeatures;
michael@0 116
michael@0 117 /* A feature status from nsIGfxInfo */
michael@0 118 int32_t mFeatureStatus;
michael@0 119
michael@0 120 VersionComparisonOp mComparisonOp;
michael@0 121
michael@0 122 /* versions are assumed to be A.B.C.D packed as 0xAAAABBBBCCCCDDDD */
michael@0 123 uint64_t mDriverVersion;
michael@0 124 uint64_t mDriverVersionMax;
michael@0 125 static uint64_t allDriverVersions;
michael@0 126
michael@0 127 const char *mSuggestedVersion;
michael@0 128
michael@0 129 static const GfxDeviceFamily* GetDeviceFamily(DeviceFamily id);
michael@0 130 static GfxDeviceFamily* mDeviceFamilies[DeviceFamilyMax];
michael@0 131
michael@0 132 static const nsAString& GetDeviceVendor(DeviceVendor id);
michael@0 133 static nsAString* mDeviceVendors[DeviceVendorMax];
michael@0 134
michael@0 135 nsString mModel, mHardware, mProduct, mManufacturer;
michael@0 136 };
michael@0 137
michael@0 138 #define GFX_DRIVER_VERSION(a,b,c,d) \
michael@0 139 ((uint64_t(a)<<48) | (uint64_t(b)<<32) | (uint64_t(c)<<16) | uint64_t(d))
michael@0 140
michael@0 141 inline uint64_t
michael@0 142 V(uint32_t a, uint32_t b, uint32_t c, uint32_t d)
michael@0 143 {
michael@0 144 // We make sure every driver number is padded by 0s, this will allow us the
michael@0 145 // easiest 'compare as if decimals' approach. See ParseDriverVersion for a
michael@0 146 // more extensive explanation of this approach.
michael@0 147 while (b > 0 && b < 1000) {
michael@0 148 b *= 10;
michael@0 149 }
michael@0 150 while (c > 0 && c < 1000) {
michael@0 151 c *= 10;
michael@0 152 }
michael@0 153 while (d > 0 && d < 1000) {
michael@0 154 d *= 10;
michael@0 155 }
michael@0 156 return GFX_DRIVER_VERSION(a, b, c, d);
michael@0 157 }
michael@0 158
michael@0 159 // All destination string storage needs to have at least 5 bytes available.
michael@0 160 inline bool SplitDriverVersion(const char *aSource, char *aAStr, char *aBStr, char *aCStr, char *aDStr)
michael@0 161 {
michael@0 162 // sscanf doesn't do what we want here to we parse this manually.
michael@0 163 int len = strlen(aSource);
michael@0 164 char *dest[4] = { aAStr, aBStr, aCStr, aDStr };
michael@0 165 unsigned destIdx = 0;
michael@0 166 unsigned destPos = 0;
michael@0 167
michael@0 168 for (int i = 0; i < len; i++) {
michael@0 169 if (destIdx > ArrayLength(dest)) {
michael@0 170 // Invalid format found. Ensure we don't access dest beyond bounds.
michael@0 171 return false;
michael@0 172 }
michael@0 173
michael@0 174 if (aSource[i] == '.') {
michael@0 175 dest[destIdx++][destPos] = 0;
michael@0 176 destPos = 0;
michael@0 177 continue;
michael@0 178 }
michael@0 179
michael@0 180 if (destPos > 3) {
michael@0 181 // Ignore more than 4 chars. Ensure we never access dest[destIdx]
michael@0 182 // beyond its bounds.
michael@0 183 continue;
michael@0 184 }
michael@0 185
michael@0 186 dest[destIdx][destPos++] = aSource[i];
michael@0 187 }
michael@0 188
michael@0 189 // Add last terminator.
michael@0 190 dest[destIdx][destPos] = 0;
michael@0 191
michael@0 192 if (destIdx != ArrayLength(dest) - 1) {
michael@0 193 return false;
michael@0 194 }
michael@0 195 return true;
michael@0 196 }
michael@0 197
michael@0 198 // This allows us to pad driver version 'substrings' with 0s, this
michael@0 199 // effectively allows us to treat the version numbers as 'decimals'. This is
michael@0 200 // a little strange but this method seems to do the right thing for all
michael@0 201 // different vendor's driver strings. i.e. .98 will become 9800, which is
michael@0 202 // larger than .978 which would become 9780.
michael@0 203 inline void PadDriverDecimal(char *aString)
michael@0 204 {
michael@0 205 for (int i = 0; i < 4; i++) {
michael@0 206 if (!aString[i]) {
michael@0 207 for (int c = i; c < 4; c++) {
michael@0 208 aString[c] = '0';
michael@0 209 }
michael@0 210 break;
michael@0 211 }
michael@0 212 }
michael@0 213 aString[4] = 0;
michael@0 214 }
michael@0 215
michael@0 216 inline bool
michael@0 217 ParseDriverVersion(const nsAString& aVersion, uint64_t *aNumericVersion)
michael@0 218 {
michael@0 219 *aNumericVersion = 0;
michael@0 220
michael@0 221 #if defined(XP_WIN)
michael@0 222 int a, b, c, d;
michael@0 223 char aStr[8], bStr[8], cStr[8], dStr[8];
michael@0 224 /* honestly, why do I even bother */
michael@0 225 if (!SplitDriverVersion(NS_LossyConvertUTF16toASCII(aVersion).get(), aStr, bStr, cStr, dStr))
michael@0 226 return false;
michael@0 227
michael@0 228 PadDriverDecimal(bStr);
michael@0 229 PadDriverDecimal(cStr);
michael@0 230 PadDriverDecimal(dStr);
michael@0 231
michael@0 232 a = atoi(aStr);
michael@0 233 b = atoi(bStr);
michael@0 234 c = atoi(cStr);
michael@0 235 d = atoi(dStr);
michael@0 236
michael@0 237 if (a < 0 || a > 0xffff) return false;
michael@0 238 if (b < 0 || b > 0xffff) return false;
michael@0 239 if (c < 0 || c > 0xffff) return false;
michael@0 240 if (d < 0 || d > 0xffff) return false;
michael@0 241
michael@0 242 *aNumericVersion = GFX_DRIVER_VERSION(a, b, c, d);
michael@0 243 return true;
michael@0 244 #elif defined(ANDROID)
michael@0 245 // Can't use aVersion.ToInteger() because that's not compiled into our code
michael@0 246 // unless we have XPCOM_GLUE_AVOID_NSPR disabled.
michael@0 247 *aNumericVersion = atoi(NS_LossyConvertUTF16toASCII(aVersion).get());
michael@0 248 return true;
michael@0 249 #else
michael@0 250 return false;
michael@0 251 #endif
michael@0 252 }
michael@0 253
michael@0 254 }
michael@0 255 }
michael@0 256
michael@0 257 #endif /*__mozilla_widget_GfxDriverInfo_h__ */

mercurial