Backed out changeset b71c8c052463 (bug 1943846) for causing mass failures. CLOSED...
[gecko.git] / widget / GfxDriverInfo.h
blob3917c0a36219f94adb98f04114a8acd39c3a5b55
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"
10 #include "nsTArray.h"
12 // Macros for adding a blocklist item to the static list. _EXT variants
13 // allow one to specify all available parameters, including those available
14 // only on specific platforms (e.g. desktop environment and driver vendor
15 // for Linux.)
17 #define APPEND_TO_DRIVER_BLOCKLIST_EXT( \
18 os, screen, battery, windowProtocol, driverVendor, devices, feature, \
19 featureStatus, driverComparator, driverVersion, ruleId, suggestedVersion) \
20 sDriverInfo->AppendElement(GfxDriverInfo( \
21 os, screen, battery, \
22 (nsAString&)GfxDriverInfo::GetWindowProtocol(windowProtocol), \
23 (nsAString&)GfxDriverInfo::GetDeviceVendor(devices), \
24 (nsAString&)GfxDriverInfo::GetDriverVendor(driverVendor), \
25 (GfxDeviceFamily*)GfxDriverInfo::GetDeviceFamily(devices), feature, \
26 featureStatus, driverComparator, driverVersion, ruleId, \
27 suggestedVersion))
29 #define APPEND_TO_DRIVER_BLOCKLIST(os, devices, feature, featureStatus, \
30 driverComparator, driverVersion, ruleId, \
31 suggestedVersion) \
32 APPEND_TO_DRIVER_BLOCKLIST_EXT( \
33 os, ScreenSizeStatus::All, BatteryStatus::All, WindowProtocol::All, \
34 DriverVendor::All, devices, feature, featureStatus, driverComparator, \
35 driverVersion, ruleId, suggestedVersion)
37 #define APPEND_TO_DRIVER_BLOCKLIST2_EXT( \
38 os, screen, battery, windowProtocol, driverVendor, devices, feature, \
39 featureStatus, driverComparator, driverVersion, ruleId) \
40 sDriverInfo->AppendElement(GfxDriverInfo( \
41 os, screen, battery, \
42 (nsAString&)GfxDriverInfo::GetWindowProtocol(windowProtocol), \
43 (nsAString&)GfxDriverInfo::GetDeviceVendor(devices), \
44 (nsAString&)GfxDriverInfo::GetDriverVendor(driverVendor), \
45 (GfxDeviceFamily*)GfxDriverInfo::GetDeviceFamily(devices), feature, \
46 featureStatus, driverComparator, driverVersion, ruleId))
48 #define APPEND_TO_DRIVER_BLOCKLIST2(os, devices, feature, featureStatus, \
49 driverComparator, driverVersion, ruleId) \
50 APPEND_TO_DRIVER_BLOCKLIST2_EXT( \
51 os, ScreenSizeStatus::All, BatteryStatus::All, WindowProtocol::All, \
52 DriverVendor::All, devices, feature, featureStatus, driverComparator, \
53 driverVersion, ruleId)
55 #define APPEND_TO_DRIVER_BLOCKLIST_RANGE_EXT( \
56 os, screen, battery, windowProtocol, driverVendor, devices, feature, \
57 featureStatus, driverComparator, driverVersion, driverVersionMax, ruleId, \
58 suggestedVersion) \
59 do { \
60 MOZ_ASSERT((driverComparator) == DRIVER_BETWEEN_EXCLUSIVE || \
61 (driverComparator) == DRIVER_BETWEEN_INCLUSIVE || \
62 (driverComparator) == DRIVER_BETWEEN_INCLUSIVE_START); \
63 GfxDriverInfo info( \
64 os, screen, battery, \
65 (nsAString&)GfxDriverInfo::GetWindowProtocol(windowProtocol), \
66 (nsAString&)GfxDriverInfo::GetDeviceVendor(devices), \
67 (nsAString&)GfxDriverInfo::GetDriverVendor(driverVendor), \
68 (GfxDeviceFamily*)GfxDriverInfo::GetDeviceFamily(devices), feature, \
69 featureStatus, driverComparator, driverVersion, ruleId, \
70 suggestedVersion); \
71 info.mDriverVersionMax = driverVersionMax; \
72 sDriverInfo->AppendElement(info); \
73 } while (false)
75 #define APPEND_TO_DRIVER_BLOCKLIST_RANGE( \
76 os, devices, feature, featureStatus, driverComparator, driverVersion, \
77 driverVersionMax, ruleId, suggestedVersion) \
78 APPEND_TO_DRIVER_BLOCKLIST_RANGE_EXT( \
79 os, ScreenSizeStatus::All, BatteryStatus::All, WindowProtocol::All, \
80 DriverVendor::All, devices, feature, featureStatus, driverComparator, \
81 driverVersion, driverVersionMax, ruleId, suggestedVersion)
83 #define APPEND_TO_DRIVER_BLOCKLIST_RANGE_GPU2_EXT( \
84 os, screen, battery, windowProtocol, driverVendor, devices, feature, \
85 featureStatus, driverComparator, driverVersion, driverVersionMax, ruleId, \
86 suggestedVersion) \
87 do { \
88 MOZ_ASSERT((driverComparator) == DRIVER_BETWEEN_EXCLUSIVE || \
89 (driverComparator) == DRIVER_BETWEEN_INCLUSIVE || \
90 (driverComparator) == DRIVER_BETWEEN_INCLUSIVE_START); \
91 GfxDriverInfo info( \
92 os, screen, battery, \
93 (nsAString&)GfxDriverInfo::GetWindowProtocol(windowProtocol), \
94 (nsAString&)GfxDriverInfo::GetDeviceVendor(devices), \
95 (nsAString&)GfxDriverInfo::GetDriverVendor(driverVendor), \
96 (GfxDeviceFamily*)GfxDriverInfo::GetDeviceFamily(devices), feature, \
97 featureStatus, driverComparator, driverVersion, ruleId, \
98 suggestedVersion, false, true); \
99 info.mDriverVersionMax = driverVersionMax; \
100 sDriverInfo->AppendElement(info); \
101 } while (false)
103 #define APPEND_TO_DRIVER_BLOCKLIST_RANGE_GPU2( \
104 os, devices, feature, featureStatus, driverComparator, driverVersion, \
105 driverVersionMax, ruleId, suggestedVersion) \
106 APPEND_TO_DRIVER_BLOCKLIST_RANGE_GPU2_EXT( \
107 os, ScreenSizeStatus::All, BatteryStatus::All, WindowProtocol::All, \
108 DriverVendor::All, devices, feature, featureStatus, driverComparator, \
109 driverVersion, driverVersionMax, ruleId, suggestedVersion)
111 namespace mozilla {
112 namespace widget {
114 enum class OperatingSystem : uint8_t {
115 Unknown,
116 #define GFXINFO_OS(id, name) id,
117 #include "mozilla/widget/GfxInfoOperatingSystemDefs.h"
118 #undef GFXINFO_OS
119 Count
122 enum VersionComparisonOp {
123 #define GFXINFO_DRIVER_VERSION_CMP(id) DRIVER_##id,
124 #include "mozilla/widget/GfxInfoDriverVersionCmpDefs.h"
125 #undef GFXINFO_DRIVER_VERSION_CMP
126 DRIVER_COUNT
129 enum class DeviceFamily : uint8_t {
130 All,
131 IntelAll,
132 NvidiaAll,
133 AtiAll,
134 MicrosoftAll,
135 ParallelsAll,
136 QualcommAll,
137 AppleAll,
138 AmazonAll,
139 IntelGMA500,
140 IntelGMA900,
141 IntelGMA950,
142 IntelGMA3150,
143 IntelGMAX3000,
144 IntelGMAX4500HD,
145 IntelHDGraphicsToIvyBridge,
146 IntelHDGraphicsToSandyBridge,
147 IntelHaswell,
148 IntelSandyBridge,
149 IntelGen7Baytrail,
150 IntelSkylake,
151 IntelKabyLake,
152 IntelHD520,
153 IntelMobileHDGraphics,
154 IntelMeteorLake,
155 IntelArrowlake,
156 IntelGen12,
157 NvidiaBlockD3D9Layers,
158 RadeonX1000,
159 RadeonCaicos,
160 RadeonBlockZeroVideoCopy,
161 Geforce7300GT,
162 Nvidia310M,
163 Nvidia8800GTS,
164 NvidiaPascal,
165 Bug1137716,
166 Bug1116812,
167 Bug1155608,
168 Bug1207665,
169 Bug1447141,
170 AmdR600,
171 IntelWebRenderBlocked,
172 NvidiaWebRenderBlocked,
177 enum class DeviceVendor : uint8_t {
178 #define GFXINFO_DEVICE_VENDOR(id, name) id,
179 #include "mozilla/widget/GfxInfoDeviceVendorDefs.h"
180 #undef GFXINFO_DEVICE_VENDOR
184 enum DriverVendor : uint8_t {
185 #define GFXINFO_DRIVER_VENDOR(id, name) id,
186 #include "mozilla/widget/GfxInfoDriverVendorDefs.h"
187 #undef GFXINFO_DRIVER_VENDOR
191 enum class WindowProtocol : uint8_t {
192 #define GFXINFO_WINDOW_PROTOCOL(id, name) id,
193 #include "mozilla/widget/GfxInfoWindowProtocolDefs.h"
194 #undef GFXINFO_WINDOW_PROTOCOL
198 enum class BatteryStatus : uint8_t { All, Present, None };
200 enum class ScreenSizeStatus : uint8_t {
201 All,
202 Small, // <= 1900x1200
203 SmallAndMedium, // <= 3440x1440
204 Medium, // <= 3440x1440 && > 1900x1200
205 MediumAndLarge, // >1900x1200
206 Large // > 3440x1440
209 /* Array of devices to match, or an empty array for all devices */
210 class GfxDeviceFamily final {
211 public:
212 GfxDeviceFamily() = default;
214 void Append(const nsAString& aDeviceId);
215 void AppendRange(int32_t aBeginDeviceId, int32_t aEndDeviceId);
217 bool IsEmpty() const { return mIds.IsEmpty() && mRanges.IsEmpty(); }
219 nsresult Contains(nsAString& aDeviceId) const;
221 private:
222 struct DeviceRange {
223 int32_t mBegin;
224 int32_t mEnd;
227 CopyableTArray<nsString> mIds;
228 CopyableTArray<DeviceRange> mRanges;
231 struct GfxDriverInfo {
232 // If |ownDevices| is true, you are transferring ownership of the devices
233 // array, and it will be deleted when this GfxDriverInfo is destroyed.
234 GfxDriverInfo(OperatingSystem os, ScreenSizeStatus aScreen,
235 BatteryStatus aBattery, const nsAString& windowProtocol,
236 const nsAString& vendor, const nsAString& driverVendor,
237 GfxDeviceFamily* devices, int32_t feature,
238 int32_t featureStatus, VersionComparisonOp op,
239 uint64_t driverVersion, const char* ruleId,
240 const char* suggestedVersion = nullptr, bool ownDevices = false,
241 bool gpu2 = false);
243 GfxDriverInfo();
244 GfxDriverInfo(const GfxDriverInfo&);
245 ~GfxDriverInfo();
247 OperatingSystem mOperatingSystem;
248 uint32_t mOperatingSystemVersion;
249 ScreenSizeStatus mScreen;
250 BatteryStatus mBattery;
251 nsString mWindowProtocol;
253 nsString mAdapterVendor;
254 nsString mDriverVendor;
256 const GfxDeviceFamily* mDevices;
258 // Whether the mDevices array should be deleted when this structure is
259 // deallocated. False by default.
260 bool mDeleteDevices;
262 /* A feature from nsIGfxInfo, or a wildcard set of features */
263 int32_t mFeature;
264 /* Block all features */
265 static constexpr int32_t allFeatures = -1;
266 /* Block all features not permitted by OnlyAllowFeatureOnKnownConfig */
267 static constexpr int32_t optionalFeatures = -2;
269 /* A feature status from nsIGfxInfo */
270 int32_t mFeatureStatus;
272 VersionComparisonOp mComparisonOp;
274 /* versions are assumed to be A.B.C.D packed as 0xAAAABBBBCCCCDDDD */
275 uint64_t mDriverVersion;
276 uint64_t mDriverVersionMax;
277 static constexpr uint64_t allDriverVersions = ~(uint64_t(0));
279 const char* mSuggestedVersion;
280 nsCString mRuleId;
282 static const GfxDeviceFamily* GetDeviceFamily(DeviceFamily id);
283 static GfxDeviceFamily*
284 sDeviceFamilies[static_cast<size_t>(DeviceFamily::Max)];
286 static const nsAString& GetWindowProtocol(WindowProtocol id);
287 static nsString* sWindowProtocol[static_cast<size_t>(WindowProtocol::Max)];
289 static const nsAString& GetDeviceVendor(DeviceVendor id);
290 static const nsAString& GetDeviceVendor(DeviceFamily id);
291 static nsString* sDeviceVendors[static_cast<size_t>(DeviceVendor::Max)];
293 static const nsAString& GetDriverVendor(DriverVendor id);
294 static nsString* sDriverVendors[static_cast<size_t>(DriverVendor::Max)];
296 nsString mModel, mHardware, mProduct, mManufacturer;
298 bool mGpu2;
301 inline uint64_t DriverVersion(uint32_t a, uint32_t b, uint32_t c, uint32_t d) {
302 return (uint64_t(a) << 48) | (uint64_t(b) << 32) | (uint64_t(c) << 16) |
303 uint64_t(d);
306 inline uint64_t V(uint32_t a, uint32_t b, uint32_t c, uint32_t d) {
307 #ifdef XP_WIN
308 // We make sure every driver number is padded by 0s, this will allow us the
309 // easiest 'compare as if decimals' approach. See ParseDriverVersion for a
310 // more extensive explanation of this approach.
311 while (b > 0 && b < 1000) {
312 b *= 10;
314 while (c > 0 && c < 1000) {
315 c *= 10;
317 while (d > 0 && d < 1000) {
318 d *= 10;
320 #endif
321 return DriverVersion(a, b, c, d);
324 // All destination string storage needs to have at least 5 bytes available.
325 inline bool SplitDriverVersion(const char* aSource, char* aAStr, char* aBStr,
326 char* aCStr, char* aDStr) {
327 // sscanf doesn't do what we want here to we parse this manually.
328 int len = strlen(aSource);
330 // This "4" is hardcoded in a few places, including once as a 3.
331 char* dest[4] = {aAStr, aBStr, aCStr, aDStr};
332 unsigned destIdx = 0;
333 unsigned destPos = 0;
335 for (int i = 0; i < len; i++) {
336 if (destIdx >= 4) {
337 // Invalid format found. Ensure we don't access dest beyond bounds.
338 return false;
341 if (aSource[i] == '.') {
342 MOZ_ASSERT(destIdx < 4 && destPos <= 4);
343 dest[destIdx++][destPos] = 0;
344 destPos = 0;
345 continue;
348 if (destPos > 3) {
349 // Ignore more than 4 chars. Ensure we never access dest[destIdx]
350 // beyond its bounds.
351 continue;
354 MOZ_ASSERT(destIdx < 4 && destPos < 4);
355 dest[destIdx][destPos++] = aSource[i];
358 // Take care of the trailing period
359 if (destIdx >= 4) {
360 return false;
363 // Add last terminator.
364 MOZ_ASSERT(destIdx < 4 && destPos <= 4);
365 dest[destIdx][destPos] = 0;
366 for (int unusedDestIdx = destIdx + 1; unusedDestIdx < 4; unusedDestIdx++) {
367 dest[unusedDestIdx][0] = 0;
370 if (destIdx != 3) {
371 return false;
373 return true;
376 // This allows us to pad driver version 'substrings' with 0s, this
377 // effectively allows us to treat the version numbers as 'decimals'. This is
378 // a little strange but this method seems to do the right thing for all
379 // different vendor's driver strings. i.e. .98 will become 9800, which is
380 // larger than .978 which would become 9780.
381 inline void PadDriverDecimal(char* aString) {
382 for (int i = 0; i < 4; i++) {
383 if (!aString[i]) {
384 for (int c = i; c < 4; c++) {
385 aString[c] = '0';
387 break;
390 aString[4] = 0;
393 inline bool ParseDriverVersion(const nsAString& aVersion,
394 uint64_t* aNumericVersion) {
395 *aNumericVersion = 0;
397 #ifndef ANDROID
398 int a, b, c, d;
399 char aStr[8], bStr[8], cStr[8], dStr[8];
400 /* honestly, why do I even bother */
401 if (!SplitDriverVersion(NS_LossyConvertUTF16toASCII(aVersion).get(), aStr,
402 bStr, cStr, dStr))
403 return false;
405 # ifdef XP_WIN
406 PadDriverDecimal(bStr);
407 PadDriverDecimal(cStr);
408 PadDriverDecimal(dStr);
409 # endif
411 a = atoi(aStr);
412 b = atoi(bStr);
413 c = atoi(cStr);
414 d = atoi(dStr);
416 if (a < 0 || a > 0xffff) return false;
417 if (b < 0 || b > 0xffff) return false;
418 if (c < 0 || c > 0xffff) return false;
419 if (d < 0 || d > 0xffff) return false;
421 *aNumericVersion = DriverVersion(a, b, c, d);
422 #else
423 // Can't use aVersion.ToInteger() because that's not compiled into our code
424 // unless we have XPCOM_GLUE_AVOID_NSPR disabled.
425 *aNumericVersion = atoi(NS_LossyConvertUTF16toASCII(aVersion).get());
426 #endif
427 MOZ_ASSERT(*aNumericVersion != GfxDriverInfo::allDriverVersions);
428 return true;
431 } // namespace widget
432 } // namespace mozilla
434 #endif /*__mozilla_widget_GfxDriverInfo_h__ */