Bug 1688354 [wpt PR 27298] - Treat 'rem' as an absolute unit for font size, a=testonly
[gecko.git] / widget / GfxDriverInfo.h
bloba69cb1d853235a6f034d15e5fca6c0a0e0608191
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 IntelHD520,
187 IntelMobileHDGraphics,
188 NvidiaBlockD3D9Layers,
189 RadeonX1000,
190 RadeonCaicos,
191 Geforce7300GT,
192 Nvidia310M,
193 Nvidia8800GTS,
194 Bug1137716,
195 Bug1116812,
196 Bug1155608,
197 Bug1207665,
198 Bug1447141,
199 AmdR600,
200 NvidiaBlockWebRender,
201 NvidiaRolloutWebRender,
202 IntelRolloutWebRender,
203 IntelModernRolloutWebRender,
204 AtiRolloutWebRender,
209 enum class DeviceVendor : uint8_t {
210 All, // There is an assumption that this is the first enum
211 Intel,
212 NVIDIA,
213 ATI,
214 Microsoft,
215 Parallels,
216 VMWare,
217 VirtualBox,
218 Qualcomm,
219 MicrosoftBasic,
220 MicrosoftHyperV,
221 Apple,
222 Amazon,
227 enum DriverVendor : uint8_t {
228 All, // There is an assumption that this is the first enum
229 // Wildcard for all Mesa drivers.
230 MesaAll,
231 // Note that the following list of Mesa drivers is not comprehensive; we pull
232 // the DRI driver at runtime. These drivers are provided for convenience when
233 // populating the local blocklist.
234 MesaLLVMPipe,
235 MesaSoftPipe,
236 MesaSWRast,
237 // Nouveau: Open-source nvidia
238 MesaNouveau,
239 // A generic ID to be provided when we can't determine the DRI driver on Mesa.
240 MesaUnknown,
241 // Wildcard for all non-Mesa drivers.
242 NonMesaAll,
243 // Wildcard for all hardware Mesa drivers.
244 HardwareMesaAll,
245 // Wildcard for all software Mesa drivers.
246 SoftwareMesaAll,
251 enum class DesktopEnvironment : uint8_t {
252 All, // There is an assumption that this is the first enum
253 GNOME,
254 KDE,
255 XFCE,
256 Cinnamon,
257 Enlightenment,
258 LXDE,
259 Openbox,
261 Mate,
262 Unity,
263 Pantheon,
264 LXQT,
265 Deepin,
266 Dwm,
267 Budgie,
268 Unknown,
272 enum class WindowProtocol : uint8_t {
273 All, // There is an assumption that this is the first enum
274 X11,
275 XWayland,
276 Wayland,
277 WaylandDRM,
278 // Wildcard for all Wayland variants, excluding XWayland.
279 WaylandAll,
280 // Wildcard for all X11 variants, including XWayland.
281 X11All,
285 enum class BatteryStatus : uint8_t { All, Present, None };
287 enum class ScreenSizeStatus : uint8_t {
288 All,
289 Small, // <= 1900x1200
290 SmallAndMedium, // <= 3440x1440
291 Medium, // <= 3440x1440 && > 1900x1200
292 MediumAndLarge, // >1900x1200
293 Large // > 3440x1440
296 /* Array of devices to match, or an empty array for all devices */
297 class GfxDeviceFamily final {
298 public:
299 GfxDeviceFamily() = default;
301 void Append(const nsAString& aDeviceId);
302 void AppendRange(int32_t aBeginDeviceId, int32_t aEndDeviceId);
304 bool IsEmpty() const { return mIds.IsEmpty() && mRanges.IsEmpty(); }
306 nsresult Contains(nsAString& aDeviceId) const;
308 private:
309 struct DeviceRange {
310 int32_t mBegin;
311 int32_t mEnd;
314 CopyableTArray<nsString> mIds;
315 CopyableTArray<DeviceRange> mRanges;
318 struct GfxDriverInfo {
319 // If |ownDevices| is true, you are transferring ownership of the devices
320 // array, and it will be deleted when this GfxDriverInfo is destroyed.
321 GfxDriverInfo(OperatingSystem os, ScreenSizeStatus aScreen,
322 BatteryStatus aBattery, const nsAString& desktopEnv,
323 const nsAString& windowProtocol, const nsAString& vendor,
324 const nsAString& driverVendor, GfxDeviceFamily* devices,
325 int32_t feature, int32_t featureStatus, VersionComparisonOp op,
326 uint64_t driverVersion, const char* ruleId,
327 const char* suggestedVersion = nullptr, bool ownDevices = false,
328 bool gpu2 = false);
330 GfxDriverInfo();
331 GfxDriverInfo(const GfxDriverInfo&);
332 ~GfxDriverInfo();
334 OperatingSystem mOperatingSystem;
335 uint32_t mOperatingSystemVersion;
336 ScreenSizeStatus mScreen;
337 BatteryStatus mBattery;
338 nsString mDesktopEnvironment;
339 nsString mWindowProtocol;
341 nsString mAdapterVendor;
342 nsString mDriverVendor;
344 const GfxDeviceFamily* mDevices;
346 // Whether the mDevices array should be deleted when this structure is
347 // deallocated. False by default.
348 bool mDeleteDevices;
350 /* A feature from nsIGfxInfo, or all features */
351 int32_t mFeature;
352 static int32_t allFeatures;
354 /* A feature status from nsIGfxInfo */
355 int32_t mFeatureStatus;
357 VersionComparisonOp mComparisonOp;
359 /* versions are assumed to be A.B.C.D packed as 0xAAAABBBBCCCCDDDD */
360 uint64_t mDriverVersion;
361 uint64_t mDriverVersionMax;
362 static uint64_t allDriverVersions;
364 const char* mSuggestedVersion;
365 nsCString mRuleId;
367 static const GfxDeviceFamily* GetDeviceFamily(DeviceFamily id);
368 static GfxDeviceFamily*
369 sDeviceFamilies[static_cast<size_t>(DeviceFamily::Max)];
371 static const nsAString& GetDesktopEnvironment(DesktopEnvironment id);
372 static nsAString*
373 sDesktopEnvironment[static_cast<size_t>(DesktopEnvironment::Max)];
375 static const nsAString& GetWindowProtocol(WindowProtocol id);
376 static nsAString* sWindowProtocol[static_cast<size_t>(WindowProtocol::Max)];
378 static const nsAString& GetDeviceVendor(DeviceVendor id);
379 static const nsAString& GetDeviceVendor(DeviceFamily id);
380 static nsAString* sDeviceVendors[static_cast<size_t>(DeviceVendor::Max)];
382 static const nsAString& GetDriverVendor(DriverVendor id);
383 static nsAString* sDriverVendors[static_cast<size_t>(DriverVendor::Max)];
385 nsString mModel, mHardware, mProduct, mManufacturer;
387 bool mGpu2;
390 #define GFX_DRIVER_VERSION(a, b, c, d) \
391 ((uint64_t(a) << 48) | (uint64_t(b) << 32) | (uint64_t(c) << 16) | \
392 uint64_t(d))
394 inline uint64_t V(uint32_t a, uint32_t b, uint32_t c, uint32_t d) {
395 // We make sure every driver number is padded by 0s, this will allow us the
396 // easiest 'compare as if decimals' approach. See ParseDriverVersion for a
397 // more extensive explanation of this approach.
398 while (b > 0 && b < 1000) {
399 b *= 10;
401 while (c > 0 && c < 1000) {
402 c *= 10;
404 while (d > 0 && d < 1000) {
405 d *= 10;
407 return GFX_DRIVER_VERSION(a, b, c, d);
410 // All destination string storage needs to have at least 5 bytes available.
411 inline bool SplitDriverVersion(const char* aSource, char* aAStr, char* aBStr,
412 char* aCStr, char* aDStr) {
413 // sscanf doesn't do what we want here to we parse this manually.
414 int len = strlen(aSource);
416 // This "4" is hardcoded in a few places, including once as a 3.
417 char* dest[4] = {aAStr, aBStr, aCStr, aDStr};
418 unsigned destIdx = 0;
419 unsigned destPos = 0;
421 for (int i = 0; i < len; i++) {
422 if (destIdx >= 4) {
423 // Invalid format found. Ensure we don't access dest beyond bounds.
424 return false;
427 if (aSource[i] == '.') {
428 MOZ_ASSERT(destIdx < 4 && destPos <= 4);
429 dest[destIdx++][destPos] = 0;
430 destPos = 0;
431 continue;
434 if (destPos > 3) {
435 // Ignore more than 4 chars. Ensure we never access dest[destIdx]
436 // beyond its bounds.
437 continue;
440 MOZ_ASSERT(destIdx < 4 && destPos < 4);
441 dest[destIdx][destPos++] = aSource[i];
444 // Take care of the trailing period
445 if (destIdx >= 4) {
446 return false;
449 // Add last terminator.
450 MOZ_ASSERT(destIdx < 4 && destPos <= 4);
451 dest[destIdx][destPos] = 0;
453 if (destIdx != 3) {
454 return false;
456 return true;
459 // This allows us to pad driver version 'substrings' with 0s, this
460 // effectively allows us to treat the version numbers as 'decimals'. This is
461 // a little strange but this method seems to do the right thing for all
462 // different vendor's driver strings. i.e. .98 will become 9800, which is
463 // larger than .978 which would become 9780.
464 inline void PadDriverDecimal(char* aString) {
465 for (int i = 0; i < 4; i++) {
466 if (!aString[i]) {
467 for (int c = i; c < 4; c++) {
468 aString[c] = '0';
470 break;
473 aString[4] = 0;
476 inline bool ParseDriverVersion(const nsAString& aVersion,
477 uint64_t* aNumericVersion) {
478 *aNumericVersion = 0;
480 #if defined(XP_WIN) || defined(MOZ_X11)
481 int a, b, c, d;
482 char aStr[8], bStr[8], cStr[8], dStr[8];
483 /* honestly, why do I even bother */
484 if (!SplitDriverVersion(NS_LossyConvertUTF16toASCII(aVersion).get(), aStr,
485 bStr, cStr, dStr))
486 return false;
488 PadDriverDecimal(bStr);
489 PadDriverDecimal(cStr);
490 PadDriverDecimal(dStr);
492 a = atoi(aStr);
493 b = atoi(bStr);
494 c = atoi(cStr);
495 d = atoi(dStr);
497 if (a < 0 || a > 0xffff) return false;
498 if (b < 0 || b > 0xffff) return false;
499 if (c < 0 || c > 0xffff) return false;
500 if (d < 0 || d > 0xffff) return false;
502 *aNumericVersion = GFX_DRIVER_VERSION(a, b, c, d);
503 MOZ_ASSERT(*aNumericVersion != GfxDriverInfo::allDriverVersions);
504 return true;
505 #elif defined(ANDROID)
506 // Can't use aVersion.ToInteger() because that's not compiled into our code
507 // unless we have XPCOM_GLUE_AVOID_NSPR disabled.
508 *aNumericVersion = atoi(NS_LossyConvertUTF16toASCII(aVersion).get());
509 MOZ_ASSERT(*aNumericVersion != GfxDriverInfo::allDriverVersions);
510 return true;
511 #else
512 return false;
513 #endif
516 } // namespace widget
517 } // namespace mozilla
519 #endif /*__mozilla_widget_GfxDriverInfo_h__ */