Bug 1769628 [wpt PR 34081] - Update wpt metadata, a=testonly
[gecko.git] / widget / GfxDriverInfo.h
blobe16ca1e019faab64d890b04f9455083a75950aee
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, desktopEnv, windowProtocol, driverVendor, devices, \
19 feature, featureStatus, driverComparator, driverVersion, ruleId, \
20 suggestedVersion) \
21 sDriverInfo->AppendElement(GfxDriverInfo( \
22 os, screen, battery, \
23 (nsAString&)GfxDriverInfo::GetDesktopEnvironment(desktopEnv), \
24 (nsAString&)GfxDriverInfo::GetWindowProtocol(windowProtocol), \
25 (nsAString&)GfxDriverInfo::GetDeviceVendor(devices), \
26 (nsAString&)GfxDriverInfo::GetDriverVendor(driverVendor), \
27 (GfxDeviceFamily*)GfxDriverInfo::GetDeviceFamily(devices), feature, \
28 featureStatus, driverComparator, driverVersion, ruleId, \
29 suggestedVersion))
31 #define APPEND_TO_DRIVER_BLOCKLIST(os, devices, feature, featureStatus, \
32 driverComparator, driverVersion, ruleId, \
33 suggestedVersion) \
34 APPEND_TO_DRIVER_BLOCKLIST_EXT( \
35 os, ScreenSizeStatus::All, BatteryStatus::All, DesktopEnvironment::All, \
36 WindowProtocol::All, DriverVendor::All, devices, feature, featureStatus, \
37 driverComparator, driverVersion, ruleId, suggestedVersion)
39 #define APPEND_TO_DRIVER_BLOCKLIST2_EXT( \
40 os, screen, battery, desktopEnv, windowProtocol, driverVendor, devices, \
41 feature, featureStatus, driverComparator, driverVersion, ruleId) \
42 sDriverInfo->AppendElement(GfxDriverInfo( \
43 os, screen, battery, \
44 (nsAString&)GfxDriverInfo::GetDesktopEnvironment(desktopEnv), \
45 (nsAString&)GfxDriverInfo::GetWindowProtocol(windowProtocol), \
46 (nsAString&)GfxDriverInfo::GetDeviceVendor(devices), \
47 (nsAString&)GfxDriverInfo::GetDriverVendor(driverVendor), \
48 (GfxDeviceFamily*)GfxDriverInfo::GetDeviceFamily(devices), feature, \
49 featureStatus, driverComparator, driverVersion, ruleId))
51 #define APPEND_TO_DRIVER_BLOCKLIST2(os, devices, feature, featureStatus, \
52 driverComparator, driverVersion, ruleId) \
53 APPEND_TO_DRIVER_BLOCKLIST2_EXT( \
54 os, ScreenSizeStatus::All, BatteryStatus::All, DesktopEnvironment::All, \
55 WindowProtocol::All, DriverVendor::All, devices, feature, featureStatus, \
56 driverComparator, driverVersion, ruleId)
58 #define APPEND_TO_DRIVER_BLOCKLIST_RANGE_EXT( \
59 os, screen, battery, desktopEnv, windowProtocol, driverVendor, devices, \
60 feature, featureStatus, driverComparator, driverVersion, driverVersionMax, \
61 ruleId, suggestedVersion) \
62 do { \
63 MOZ_ASSERT((driverComparator) == DRIVER_BETWEEN_EXCLUSIVE || \
64 (driverComparator) == DRIVER_BETWEEN_INCLUSIVE || \
65 (driverComparator) == DRIVER_BETWEEN_INCLUSIVE_START); \
66 GfxDriverInfo info( \
67 os, screen, battery, \
68 (nsAString&)GfxDriverInfo::GetDesktopEnvironment(desktopEnv), \
69 (nsAString&)GfxDriverInfo::GetWindowProtocol(windowProtocol), \
70 (nsAString&)GfxDriverInfo::GetDeviceVendor(devices), \
71 (nsAString&)GfxDriverInfo::GetDriverVendor(driverVendor), \
72 (GfxDeviceFamily*)GfxDriverInfo::GetDeviceFamily(devices), feature, \
73 featureStatus, driverComparator, driverVersion, ruleId, \
74 suggestedVersion); \
75 info.mDriverVersionMax = driverVersionMax; \
76 sDriverInfo->AppendElement(info); \
77 } while (false)
79 #define APPEND_TO_DRIVER_BLOCKLIST_RANGE( \
80 os, devices, feature, featureStatus, driverComparator, driverVersion, \
81 driverVersionMax, ruleId, suggestedVersion) \
82 APPEND_TO_DRIVER_BLOCKLIST_RANGE_EXT( \
83 os, ScreenSizeStatus::All, BatteryStatus::All, DesktopEnvironment::All, \
84 WindowProtocol::All, DriverVendor::All, devices, feature, featureStatus, \
85 driverComparator, driverVersion, driverVersionMax, ruleId, \
86 suggestedVersion)
88 #define APPEND_TO_DRIVER_BLOCKLIST_RANGE_GPU2_EXT( \
89 os, screen, battery, desktopEnv, windowProtocol, driverVendor, devices, \
90 feature, featureStatus, driverComparator, driverVersion, driverVersionMax, \
91 ruleId, suggestedVersion) \
92 do { \
93 MOZ_ASSERT((driverComparator) == DRIVER_BETWEEN_EXCLUSIVE || \
94 (driverComparator) == DRIVER_BETWEEN_INCLUSIVE || \
95 (driverComparator) == DRIVER_BETWEEN_INCLUSIVE_START); \
96 GfxDriverInfo info( \
97 os, screen, battery, \
98 (nsAString&)GfxDriverInfo::GetDesktopEnvironment(desktopEnv), \
99 (nsAString&)GfxDriverInfo::GetWindowProtocol(windowProtocol), \
100 (nsAString&)GfxDriverInfo::GetDeviceVendor(devices), \
101 (nsAString&)GfxDriverInfo::GetDriverVendor(driverVendor), \
102 (GfxDeviceFamily*)GfxDriverInfo::GetDeviceFamily(devices), feature, \
103 featureStatus, driverComparator, driverVersion, ruleId, \
104 suggestedVersion, false, true); \
105 info.mDriverVersionMax = driverVersionMax; \
106 sDriverInfo->AppendElement(info); \
107 } while (false)
109 #define APPEND_TO_DRIVER_BLOCKLIST_RANGE_GPU2( \
110 os, devices, feature, featureStatus, driverComparator, driverVersion, \
111 driverVersionMax, ruleId, suggestedVersion) \
112 APPEND_TO_DRIVER_BLOCKLIST_RANGE_GPU2_EXT( \
113 os, ScreenSizeStatus::All, BatteryStatus::All, DesktopEnvironment::All, \
114 WindowProtocol::All, DriverVendor::All, devices, feature, featureStatus, \
115 driverComparator, driverVersion, driverVersionMax, ruleId, \
116 suggestedVersion)
118 namespace mozilla {
119 namespace widget {
121 enum class OperatingSystem : uint8_t {
122 Unknown,
123 Windows,
124 WindowsXP,
125 WindowsServer2003,
126 WindowsVista,
127 Windows7,
128 Windows8,
129 Windows8_1,
130 Windows10,
131 RecentWindows10,
132 NotRecentWindows10,
133 Linux,
134 OSX,
135 OSX10_5,
136 OSX10_6,
137 OSX10_7,
138 OSX10_8,
139 OSX10_9,
140 OSX10_10,
141 OSX10_11,
142 OSX10_12,
143 OSX10_13,
144 OSX10_14,
145 OSX10_15,
146 OSX11_0,
147 Android,
151 enum VersionComparisonOp {
152 DRIVER_LESS_THAN, // driver < version
153 DRIVER_BUILD_ID_LESS_THAN, // driver build id < version
154 DRIVER_LESS_THAN_OR_EQUAL, // driver <= version
155 DRIVER_BUILD_ID_LESS_THAN_OR_EQUAL, // driver build id <= version
156 DRIVER_GREATER_THAN, // driver > version
157 DRIVER_GREATER_THAN_OR_EQUAL, // driver >= version
158 DRIVER_EQUAL, // driver == version
159 DRIVER_NOT_EQUAL, // driver != version
160 DRIVER_BETWEEN_EXCLUSIVE, // driver > version && driver < versionMax
161 DRIVER_BETWEEN_INCLUSIVE, // driver >= version && driver <= versionMax
162 DRIVER_BETWEEN_INCLUSIVE_START, // driver >= version && driver < versionMax
163 DRIVER_COMPARISON_IGNORED
166 enum class DeviceFamily : uint8_t {
167 All,
168 IntelAll,
169 NvidiaAll,
170 AtiAll,
171 MicrosoftAll,
172 ParallelsAll,
173 QualcommAll,
174 AppleAll,
175 AmazonAll,
176 IntelGMA500,
177 IntelGMA900,
178 IntelGMA950,
179 IntelGMA3150,
180 IntelGMAX3000,
181 IntelGMAX4500HD,
182 IntelHDGraphicsToIvyBridge,
183 IntelHDGraphicsToSandyBridge,
184 IntelHaswell,
185 IntelSandyBridge,
186 IntelGen7Baytrail,
187 IntelSkylake,
188 IntelHD520,
189 IntelMobileHDGraphics,
190 NvidiaBlockD3D9Layers,
191 RadeonX1000,
192 RadeonCaicos,
193 RadeonBlockNoVideoCopy,
194 Geforce7300GT,
195 Nvidia310M,
196 Nvidia8800GTS,
197 Bug1137716,
198 Bug1116812,
199 Bug1155608,
200 Bug1207665,
201 Bug1447141,
202 AmdR600,
203 NvidiaRolloutWebRender,
204 IntelRolloutWebRender,
205 IntelModernRolloutWebRender,
206 IntelWebRenderBlocked,
207 NvidiaWebRenderBlocked,
208 AtiRolloutWebRender,
213 enum class DeviceVendor : uint8_t {
214 All, // There is an assumption that this is the first enum
215 Intel,
216 NVIDIA,
217 ATI,
218 Microsoft,
219 Parallels,
220 VMWare,
221 VirtualBox,
222 Qualcomm,
223 MicrosoftBasic,
224 MicrosoftHyperV,
225 Apple,
226 Amazon,
231 enum DriverVendor : uint8_t {
232 All, // There is an assumption that this is the first enum
233 // Wildcard for all Mesa drivers.
234 MesaAll,
235 // Note that the following list of Mesa drivers is not comprehensive; we pull
236 // the DRI driver at runtime. These drivers are provided for convenience when
237 // populating the local blocklist.
238 MesaLLVMPipe,
239 MesaSoftPipe,
240 MesaSWRast,
241 MesaSWUnknown,
242 // AMD
243 MesaR600,
244 // Nouveau: Open-source nvidia
245 MesaNouveau,
246 // A generic ID to be provided when we can't determine the DRI driver on Mesa.
247 MesaUnknown,
248 // Wildcard for all non-Mesa drivers.
249 NonMesaAll,
250 // Wildcard for all hardware Mesa drivers.
251 HardwareMesaAll,
252 // Wildcard for all software Mesa drivers.
253 SoftwareMesaAll,
258 enum class DesktopEnvironment : uint8_t {
259 All, // There is an assumption that this is the first enum
260 GNOME,
261 KDE,
262 XFCE,
263 Cinnamon,
264 Enlightenment,
265 LXDE,
266 Openbox,
268 Mate,
269 Unity,
270 Pantheon,
271 LXQT,
272 Deepin,
273 Dwm,
274 Budgie,
275 Sway,
276 Unknown,
280 enum class WindowProtocol : uint8_t {
281 All, // There is an assumption that this is the first enum
282 X11,
283 XWayland,
284 Wayland,
285 WaylandDRM,
286 // Wildcard for all Wayland variants, excluding XWayland.
287 WaylandAll,
288 // Wildcard for all X11 variants, including XWayland.
289 X11All,
293 enum class BatteryStatus : uint8_t { All, Present, None };
295 enum class ScreenSizeStatus : uint8_t {
296 All,
297 Small, // <= 1900x1200
298 SmallAndMedium, // <= 3440x1440
299 Medium, // <= 3440x1440 && > 1900x1200
300 MediumAndLarge, // >1900x1200
301 Large // > 3440x1440
304 /* Array of devices to match, or an empty array for all devices */
305 class GfxDeviceFamily final {
306 public:
307 GfxDeviceFamily() = default;
309 void Append(const nsAString& aDeviceId);
310 void AppendRange(int32_t aBeginDeviceId, int32_t aEndDeviceId);
312 bool IsEmpty() const { return mIds.IsEmpty() && mRanges.IsEmpty(); }
314 nsresult Contains(nsAString& aDeviceId) const;
316 private:
317 struct DeviceRange {
318 int32_t mBegin;
319 int32_t mEnd;
322 CopyableTArray<nsString> mIds;
323 CopyableTArray<DeviceRange> mRanges;
326 struct GfxDriverInfo {
327 // If |ownDevices| is true, you are transferring ownership of the devices
328 // array, and it will be deleted when this GfxDriverInfo is destroyed.
329 GfxDriverInfo(OperatingSystem os, ScreenSizeStatus aScreen,
330 BatteryStatus aBattery, const nsAString& desktopEnv,
331 const nsAString& windowProtocol, const nsAString& vendor,
332 const nsAString& driverVendor, GfxDeviceFamily* devices,
333 int32_t feature, int32_t featureStatus, VersionComparisonOp op,
334 uint64_t driverVersion, const char* ruleId,
335 const char* suggestedVersion = nullptr, bool ownDevices = false,
336 bool gpu2 = false);
338 GfxDriverInfo();
339 GfxDriverInfo(const GfxDriverInfo&);
340 ~GfxDriverInfo();
342 OperatingSystem mOperatingSystem;
343 uint32_t mOperatingSystemVersion;
344 ScreenSizeStatus mScreen;
345 BatteryStatus mBattery;
346 nsString mDesktopEnvironment;
347 nsString mWindowProtocol;
349 nsString mAdapterVendor;
350 nsString mDriverVendor;
352 const GfxDeviceFamily* mDevices;
354 // Whether the mDevices array should be deleted when this structure is
355 // deallocated. False by default.
356 bool mDeleteDevices;
358 /* A feature from nsIGfxInfo, or all features */
359 int32_t mFeature;
360 static int32_t allFeatures;
362 /* A feature status from nsIGfxInfo */
363 int32_t mFeatureStatus;
365 VersionComparisonOp mComparisonOp;
367 /* versions are assumed to be A.B.C.D packed as 0xAAAABBBBCCCCDDDD */
368 uint64_t mDriverVersion;
369 uint64_t mDriverVersionMax;
370 static uint64_t allDriverVersions;
372 const char* mSuggestedVersion;
373 nsCString mRuleId;
375 static const GfxDeviceFamily* GetDeviceFamily(DeviceFamily id);
376 static GfxDeviceFamily*
377 sDeviceFamilies[static_cast<size_t>(DeviceFamily::Max)];
379 static const nsAString& GetDesktopEnvironment(DesktopEnvironment id);
380 static nsAString*
381 sDesktopEnvironment[static_cast<size_t>(DesktopEnvironment::Max)];
383 static const nsAString& GetWindowProtocol(WindowProtocol id);
384 static nsAString* sWindowProtocol[static_cast<size_t>(WindowProtocol::Max)];
386 static const nsAString& GetDeviceVendor(DeviceVendor id);
387 static const nsAString& GetDeviceVendor(DeviceFamily id);
388 static nsAString* sDeviceVendors[static_cast<size_t>(DeviceVendor::Max)];
390 static const nsAString& GetDriverVendor(DriverVendor id);
391 static nsAString* sDriverVendors[static_cast<size_t>(DriverVendor::Max)];
393 nsString mModel, mHardware, mProduct, mManufacturer;
395 bool mGpu2;
398 inline uint64_t DriverVersion(uint32_t a, uint32_t b, uint32_t c, uint32_t d) {
399 return (uint64_t(a) << 48) | (uint64_t(b) << 32) | (uint64_t(c) << 16) |
400 uint64_t(d);
403 inline uint64_t V(uint32_t a, uint32_t b, uint32_t c, uint32_t d) {
404 #ifdef XP_WIN
405 // We make sure every driver number is padded by 0s, this will allow us the
406 // easiest 'compare as if decimals' approach. See ParseDriverVersion for a
407 // more extensive explanation of this approach.
408 while (b > 0 && b < 1000) {
409 b *= 10;
411 while (c > 0 && c < 1000) {
412 c *= 10;
414 while (d > 0 && d < 1000) {
415 d *= 10;
417 #endif
418 return DriverVersion(a, b, c, d);
421 // All destination string storage needs to have at least 5 bytes available.
422 inline bool SplitDriverVersion(const char* aSource, char* aAStr, char* aBStr,
423 char* aCStr, char* aDStr) {
424 // sscanf doesn't do what we want here to we parse this manually.
425 int len = strlen(aSource);
427 // This "4" is hardcoded in a few places, including once as a 3.
428 char* dest[4] = {aAStr, aBStr, aCStr, aDStr};
429 unsigned destIdx = 0;
430 unsigned destPos = 0;
432 for (int i = 0; i < len; i++) {
433 if (destIdx >= 4) {
434 // Invalid format found. Ensure we don't access dest beyond bounds.
435 return false;
438 if (aSource[i] == '.') {
439 MOZ_ASSERT(destIdx < 4 && destPos <= 4);
440 dest[destIdx++][destPos] = 0;
441 destPos = 0;
442 continue;
445 if (destPos > 3) {
446 // Ignore more than 4 chars. Ensure we never access dest[destIdx]
447 // beyond its bounds.
448 continue;
451 MOZ_ASSERT(destIdx < 4 && destPos < 4);
452 dest[destIdx][destPos++] = aSource[i];
455 // Take care of the trailing period
456 if (destIdx >= 4) {
457 return false;
460 // Add last terminator.
461 MOZ_ASSERT(destIdx < 4 && destPos <= 4);
462 dest[destIdx][destPos] = 0;
464 if (destIdx != 3) {
465 return false;
467 return true;
470 // This allows us to pad driver version 'substrings' with 0s, this
471 // effectively allows us to treat the version numbers as 'decimals'. This is
472 // a little strange but this method seems to do the right thing for all
473 // different vendor's driver strings. i.e. .98 will become 9800, which is
474 // larger than .978 which would become 9780.
475 inline void PadDriverDecimal(char* aString) {
476 for (int i = 0; i < 4; i++) {
477 if (!aString[i]) {
478 for (int c = i; c < 4; c++) {
479 aString[c] = '0';
481 break;
484 aString[4] = 0;
487 inline bool ParseDriverVersion(const nsAString& aVersion,
488 uint64_t* aNumericVersion) {
489 *aNumericVersion = 0;
491 #ifndef ANDROID
492 int a, b, c, d;
493 char aStr[8], bStr[8], cStr[8], dStr[8];
494 /* honestly, why do I even bother */
495 if (!SplitDriverVersion(NS_LossyConvertUTF16toASCII(aVersion).get(), aStr,
496 bStr, cStr, dStr))
497 return false;
499 # ifdef XP_WIN
500 PadDriverDecimal(bStr);
501 PadDriverDecimal(cStr);
502 PadDriverDecimal(dStr);
503 # endif
505 a = atoi(aStr);
506 b = atoi(bStr);
507 c = atoi(cStr);
508 d = atoi(dStr);
510 if (a < 0 || a > 0xffff) return false;
511 if (b < 0 || b > 0xffff) return false;
512 if (c < 0 || c > 0xffff) return false;
513 if (d < 0 || d > 0xffff) return false;
515 *aNumericVersion = DriverVersion(a, b, c, d);
516 #else
517 // Can't use aVersion.ToInteger() because that's not compiled into our code
518 // unless we have XPCOM_GLUE_AVOID_NSPR disabled.
519 *aNumericVersion = atoi(NS_LossyConvertUTF16toASCII(aVersion).get());
520 #endif
521 MOZ_ASSERT(*aNumericVersion != GfxDriverInfo::allDriverVersions);
522 return true;
525 } // namespace widget
526 } // namespace mozilla
528 #endif /*__mozilla_widget_GfxDriverInfo_h__ */