Bug 1517200 [wpt PR 14691] - Less restrictive internal column count limit., a=testonly
[gecko.git] / widget / GfxDriverInfo.h
blob5a2bddb5bf991fd2a9834669299f4547515544c1
1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* This Source Code Form is subject to the terms of the Mozilla Public
3 * License, v. 2.0. If a copy of the MPL was not distributed with this
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6 #ifndef __mozilla_widget_GfxDriverInfo_h__
7 #define __mozilla_widget_GfxDriverInfo_h__
9 #include "nsString.h"
11 // Macros for adding a blocklist item to the static list.
12 #define APPEND_TO_DRIVER_BLOCKLIST(os, vendor, devices, feature, \
13 featureStatus, driverComparator, \
14 driverVersion, ruleId, suggestedVersion) \
15 sDriverInfo->AppendElement(GfxDriverInfo( \
16 os, vendor, devices, feature, featureStatus, driverComparator, \
17 driverVersion, ruleId, suggestedVersion))
18 #define APPEND_TO_DRIVER_BLOCKLIST2(os, vendor, devices, feature, \
19 featureStatus, driverComparator, \
20 driverVersion, ruleId) \
21 sDriverInfo->AppendElement(GfxDriverInfo(os, vendor, devices, feature, \
22 featureStatus, driverComparator, \
23 driverVersion, ruleId))
25 #define APPEND_TO_DRIVER_BLOCKLIST_RANGE( \
26 os, vendor, devices, feature, featureStatus, driverComparator, \
27 driverVersion, driverVersionMax, ruleId, suggestedVersion) \
28 do { \
29 MOZ_ASSERT(driverComparator == DRIVER_BETWEEN_EXCLUSIVE || \
30 driverComparator == DRIVER_BETWEEN_INCLUSIVE || \
31 driverComparator == DRIVER_BETWEEN_INCLUSIVE_START); \
32 GfxDriverInfo info(os, vendor, devices, feature, featureStatus, \
33 driverComparator, driverVersion, ruleId, \
34 suggestedVersion); \
35 info.mDriverVersionMax = driverVersionMax; \
36 sDriverInfo->AppendElement(info); \
37 } while (false)
39 #define APPEND_TO_DRIVER_BLOCKLIST_RANGE_GPU2( \
40 os, vendor, devices, feature, featureStatus, driverComparator, \
41 driverVersion, driverVersionMax, ruleId, suggestedVersion) \
42 do { \
43 MOZ_ASSERT(driverComparator == DRIVER_BETWEEN_EXCLUSIVE || \
44 driverComparator == DRIVER_BETWEEN_INCLUSIVE || \
45 driverComparator == DRIVER_BETWEEN_INCLUSIVE_START); \
46 GfxDriverInfo info(os, vendor, devices, feature, featureStatus, \
47 driverComparator, driverVersion, ruleId, \
48 suggestedVersion, false, true); \
49 info.mDriverVersionMax = driverVersionMax; \
50 sDriverInfo->AppendElement(info); \
51 } while (false)
53 namespace mozilla {
54 namespace widget {
56 enum class OperatingSystem {
57 Unknown,
58 Windows,
59 WindowsXP,
60 WindowsServer2003,
61 WindowsVista,
62 Windows7,
63 Windows8,
64 Windows8_1,
65 Windows10,
66 Linux,
67 OSX,
68 OSX10_5,
69 OSX10_6,
70 OSX10_7,
71 OSX10_8,
72 OSX10_9,
73 OSX10_10,
74 OSX10_11,
75 OSX10_12,
76 OSX10_13,
77 Android,
78 Ios
81 enum VersionComparisonOp {
82 DRIVER_LESS_THAN, // driver < version
83 DRIVER_BUILD_ID_LESS_THAN, // driver build id < version
84 DRIVER_LESS_THAN_OR_EQUAL, // driver <= version
85 DRIVER_BUILD_ID_LESS_THAN_OR_EQUAL, // driver build id <= version
86 DRIVER_GREATER_THAN, // driver > version
87 DRIVER_GREATER_THAN_OR_EQUAL, // driver >= version
88 DRIVER_EQUAL, // driver == version
89 DRIVER_NOT_EQUAL, // driver != version
90 DRIVER_BETWEEN_EXCLUSIVE, // driver > version && driver < versionMax
91 DRIVER_BETWEEN_INCLUSIVE, // driver >= version && driver <= versionMax
92 DRIVER_BETWEEN_INCLUSIVE_START, // driver >= version && driver < versionMax
93 DRIVER_COMPARISON_IGNORED
96 enum DeviceFamily {
97 IntelGMA500,
98 IntelGMA900,
99 IntelGMA950,
100 IntelGMA3150,
101 IntelGMAX3000,
102 IntelGMAX4500HD,
103 IntelHDGraphicsToSandyBridge,
104 IntelHDGraphicsToHaswell,
105 IntelHD3000,
106 IntelMobileHDGraphics,
107 NvidiaBlockD3D9Layers,
108 RadeonX1000,
109 Geforce7300GT,
110 Nvidia310M,
111 Nvidia8800GTS,
112 Bug1137716,
113 Bug1116812,
114 Bug1155608,
115 Bug1207665,
116 Bug1447141,
117 NvidiaBlockWebRender,
118 DeviceFamilyMax
121 enum DeviceVendor {
122 VendorAll, // There is an assumption that this is the first enum
123 VendorIntel,
124 VendorNVIDIA,
125 VendorAMD,
126 VendorATI,
127 VendorMicrosoft,
128 VendorParallels,
129 VendorQualcomm,
130 DeviceVendorMax
133 /* Array of devices to match, or an empty array for all devices */
134 typedef nsTArray<nsString> GfxDeviceFamily;
136 struct GfxDriverInfo {
137 // If |ownDevices| is true, you are transferring ownership of the devices
138 // array, and it will be deleted when this GfxDriverInfo is destroyed.
139 GfxDriverInfo(OperatingSystem os, nsAString &vendor, GfxDeviceFamily *devices,
140 int32_t feature, int32_t featureStatus, VersionComparisonOp op,
141 uint64_t driverVersion, const char *ruleId,
142 const char *suggestedVersion = nullptr, bool ownDevices = false,
143 bool gpu2 = false);
145 GfxDriverInfo();
146 GfxDriverInfo(const GfxDriverInfo &);
147 ~GfxDriverInfo();
149 OperatingSystem mOperatingSystem;
150 uint32_t mOperatingSystemVersion;
152 nsString mAdapterVendor;
154 static GfxDeviceFamily *const allDevices;
155 GfxDeviceFamily *mDevices;
157 // Whether the mDevices array should be deleted when this structure is
158 // deallocated. False by default.
159 bool mDeleteDevices;
161 /* A feature from nsIGfxInfo, or all features */
162 int32_t mFeature;
163 static int32_t allFeatures;
165 /* A feature status from nsIGfxInfo */
166 int32_t mFeatureStatus;
168 VersionComparisonOp mComparisonOp;
170 /* versions are assumed to be A.B.C.D packed as 0xAAAABBBBCCCCDDDD */
171 uint64_t mDriverVersion;
172 uint64_t mDriverVersionMax;
173 static uint64_t allDriverVersions;
175 const char *mSuggestedVersion;
176 nsCString mRuleId;
178 static const GfxDeviceFamily *GetDeviceFamily(DeviceFamily id);
179 static GfxDeviceFamily *sDeviceFamilies[DeviceFamilyMax];
181 static const nsAString &GetDeviceVendor(DeviceVendor id);
182 static nsAString *sDeviceVendors[DeviceVendorMax];
184 nsString mModel, mHardware, mProduct, mManufacturer;
186 bool mGpu2;
189 #define GFX_DRIVER_VERSION(a, b, c, d) \
190 ((uint64_t(a) << 48) | (uint64_t(b) << 32) | (uint64_t(c) << 16) | \
191 uint64_t(d))
193 inline uint64_t V(uint32_t a, uint32_t b, uint32_t c, uint32_t d) {
194 // We make sure every driver number is padded by 0s, this will allow us the
195 // easiest 'compare as if decimals' approach. See ParseDriverVersion for a
196 // more extensive explanation of this approach.
197 while (b > 0 && b < 1000) {
198 b *= 10;
200 while (c > 0 && c < 1000) {
201 c *= 10;
203 while (d > 0 && d < 1000) {
204 d *= 10;
206 return GFX_DRIVER_VERSION(a, b, c, d);
209 // All destination string storage needs to have at least 5 bytes available.
210 inline bool SplitDriverVersion(const char *aSource, char *aAStr, char *aBStr,
211 char *aCStr, char *aDStr) {
212 // sscanf doesn't do what we want here to we parse this manually.
213 int len = strlen(aSource);
215 // This "4" is hardcoded in a few places, including once as a 3.
216 char *dest[4] = {aAStr, aBStr, aCStr, aDStr};
217 unsigned destIdx = 0;
218 unsigned destPos = 0;
220 for (int i = 0; i < len; i++) {
221 if (destIdx >= 4) {
222 // Invalid format found. Ensure we don't access dest beyond bounds.
223 return false;
226 if (aSource[i] == '.') {
227 MOZ_ASSERT(destIdx < 4 && destPos <= 4);
228 dest[destIdx++][destPos] = 0;
229 destPos = 0;
230 continue;
233 if (destPos > 3) {
234 // Ignore more than 4 chars. Ensure we never access dest[destIdx]
235 // beyond its bounds.
236 continue;
239 MOZ_ASSERT(destIdx < 4 && destPos < 4);
240 dest[destIdx][destPos++] = aSource[i];
243 // Take care of the trailing period
244 if (destIdx >= 4) {
245 return false;
248 // Add last terminator.
249 MOZ_ASSERT(destIdx < 4 && destPos <= 4);
250 dest[destIdx][destPos] = 0;
252 if (destIdx != 3) {
253 return false;
255 return true;
258 // This allows us to pad driver version 'substrings' with 0s, this
259 // effectively allows us to treat the version numbers as 'decimals'. This is
260 // a little strange but this method seems to do the right thing for all
261 // different vendor's driver strings. i.e. .98 will become 9800, which is
262 // larger than .978 which would become 9780.
263 inline void PadDriverDecimal(char *aString) {
264 for (int i = 0; i < 4; i++) {
265 if (!aString[i]) {
266 for (int c = i; c < 4; c++) {
267 aString[c] = '0';
269 break;
272 aString[4] = 0;
275 inline bool ParseDriverVersion(const nsAString &aVersion,
276 uint64_t *aNumericVersion) {
277 *aNumericVersion = 0;
279 #if defined(XP_WIN)
280 int a, b, c, d;
281 char aStr[8], bStr[8], cStr[8], dStr[8];
282 /* honestly, why do I even bother */
283 if (!SplitDriverVersion(NS_LossyConvertUTF16toASCII(aVersion).get(), aStr,
284 bStr, cStr, dStr))
285 return false;
287 PadDriverDecimal(bStr);
288 PadDriverDecimal(cStr);
289 PadDriverDecimal(dStr);
291 a = atoi(aStr);
292 b = atoi(bStr);
293 c = atoi(cStr);
294 d = atoi(dStr);
296 if (a < 0 || a > 0xffff) return false;
297 if (b < 0 || b > 0xffff) return false;
298 if (c < 0 || c > 0xffff) return false;
299 if (d < 0 || d > 0xffff) return false;
301 *aNumericVersion = GFX_DRIVER_VERSION(a, b, c, d);
302 MOZ_ASSERT(*aNumericVersion != GfxDriverInfo::allDriverVersions);
303 return true;
304 #elif defined(ANDROID)
305 // Can't use aVersion.ToInteger() because that's not compiled into our code
306 // unless we have XPCOM_GLUE_AVOID_NSPR disabled.
307 *aNumericVersion = atoi(NS_LossyConvertUTF16toASCII(aVersion).get());
308 MOZ_ASSERT(*aNumericVersion != GfxDriverInfo::allDriverVersions);
309 return true;
310 #else
311 return false;
312 #endif
315 } // namespace widget
316 } // namespace mozilla
318 #endif /*__mozilla_widget_GfxDriverInfo_h__ */