Bug 1885565 - Part 2: Fix up parameter ordering and kDoc descriptions in NavigationBa...
[gecko.git] / widget / GfxDriverInfo.h
bloba584c7ac3f4c10a848bb89ebdb6c4f43c0554cd2
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 Windows,
117 WindowsXP,
118 WindowsServer2003,
119 WindowsVista,
120 Windows7,
121 Windows8,
122 Windows8_1,
123 Windows10,
124 RecentWindows10,
125 NotRecentWindows10,
126 Linux,
127 OSX,
128 OSX10_5,
129 OSX10_6,
130 OSX10_7,
131 OSX10_8,
132 OSX10_9,
133 OSX10_10,
134 OSX10_11,
135 OSX10_12,
136 OSX10_13,
137 OSX10_14,
138 OSX10_15,
139 OSX11_0,
140 Android,
144 enum VersionComparisonOp {
145 DRIVER_LESS_THAN, // driver < version
146 DRIVER_BUILD_ID_LESS_THAN, // driver build id < version
147 DRIVER_LESS_THAN_OR_EQUAL, // driver <= version
148 DRIVER_BUILD_ID_LESS_THAN_OR_EQUAL, // driver build id <= version
149 DRIVER_GREATER_THAN, // driver > version
150 DRIVER_GREATER_THAN_OR_EQUAL, // driver >= version
151 DRIVER_EQUAL, // driver == version
152 DRIVER_NOT_EQUAL, // driver != version
153 DRIVER_BETWEEN_EXCLUSIVE, // driver > version && driver < versionMax
154 DRIVER_BETWEEN_INCLUSIVE, // driver >= version && driver <= versionMax
155 DRIVER_BETWEEN_INCLUSIVE_START, // driver >= version && driver < versionMax
156 DRIVER_COMPARISON_IGNORED
159 enum class DeviceFamily : uint8_t {
160 All,
161 IntelAll,
162 NvidiaAll,
163 AtiAll,
164 MicrosoftAll,
165 ParallelsAll,
166 QualcommAll,
167 AppleAll,
168 AmazonAll,
169 IntelGMA500,
170 IntelGMA900,
171 IntelGMA950,
172 IntelGMA3150,
173 IntelGMAX3000,
174 IntelGMAX4500HD,
175 IntelHDGraphicsToIvyBridge,
176 IntelHDGraphicsToSandyBridge,
177 IntelHaswell,
178 IntelSandyBridge,
179 IntelGen7Baytrail,
180 IntelSkylake,
181 IntelKabyLake,
182 IntelHD520,
183 IntelMobileHDGraphics,
184 NvidiaBlockD3D9Layers,
185 RadeonX1000,
186 RadeonCaicos,
187 RadeonBlockZeroVideoCopy,
188 Geforce7300GT,
189 Nvidia310M,
190 Nvidia8800GTS,
191 Bug1137716,
192 Bug1116812,
193 Bug1155608,
194 Bug1207665,
195 Bug1447141,
196 AmdR600,
197 IntelWebRenderBlocked,
198 NvidiaWebRenderBlocked,
203 enum class DeviceVendor : uint8_t {
204 All, // There is an assumption that this is the first enum
205 Intel,
206 NVIDIA,
207 ATI,
208 Microsoft,
209 Parallels,
210 VMWare,
211 VirtualBox,
212 Qualcomm,
213 MicrosoftBasic,
214 MicrosoftHyperV,
215 Apple,
216 Amazon,
221 enum DriverVendor : uint8_t {
222 All, // There is an assumption that this is the first enum
223 // Wildcard for all Mesa drivers.
224 MesaAll,
225 // Note that the following list of Mesa drivers is not comprehensive; we pull
226 // the DRI driver at runtime. These drivers are provided for convenience when
227 // populating the local blocklist.
228 MesaLLVMPipe,
229 MesaSoftPipe,
230 MesaSWRast,
231 MesaSWUnknown,
232 // AMD
233 MesaR600,
234 // Nouveau: Open-source nvidia
235 MesaNouveau,
236 // A generic ID to be provided when we can't determine the DRI driver on Mesa.
237 MesaUnknown,
238 // Wildcard for all non-Mesa drivers.
239 NonMesaAll,
240 // Wildcard for all hardware Mesa drivers.
241 HardwareMesaAll,
242 // Wildcard for all software Mesa drivers.
243 SoftwareMesaAll,
244 // Wildcard for all non-Intel/NVIDIA/ATI Mesa drivers.
245 MesaNonIntelNvidiaAtiAll,
246 // Running in VM.
247 MesaVM,
252 enum class WindowProtocol : uint8_t {
253 All, // There is an assumption that this is the first enum
254 X11,
255 XWayland,
256 Wayland,
257 WaylandDRM,
258 // Wildcard for all Wayland variants, excluding XWayland.
259 WaylandAll,
260 // Wildcard for all X11 variants, including XWayland.
261 X11All,
265 enum class BatteryStatus : uint8_t { All, Present, None };
267 enum class ScreenSizeStatus : uint8_t {
268 All,
269 Small, // <= 1900x1200
270 SmallAndMedium, // <= 3440x1440
271 Medium, // <= 3440x1440 && > 1900x1200
272 MediumAndLarge, // >1900x1200
273 Large // > 3440x1440
276 /* Array of devices to match, or an empty array for all devices */
277 class GfxDeviceFamily final {
278 public:
279 GfxDeviceFamily() = default;
281 void Append(const nsAString& aDeviceId);
282 void AppendRange(int32_t aBeginDeviceId, int32_t aEndDeviceId);
284 bool IsEmpty() const { return mIds.IsEmpty() && mRanges.IsEmpty(); }
286 nsresult Contains(nsAString& aDeviceId) const;
288 private:
289 struct DeviceRange {
290 int32_t mBegin;
291 int32_t mEnd;
294 CopyableTArray<nsString> mIds;
295 CopyableTArray<DeviceRange> mRanges;
298 struct GfxDriverInfo {
299 // If |ownDevices| is true, you are transferring ownership of the devices
300 // array, and it will be deleted when this GfxDriverInfo is destroyed.
301 GfxDriverInfo(OperatingSystem os, ScreenSizeStatus aScreen,
302 BatteryStatus aBattery, const nsAString& windowProtocol,
303 const nsAString& vendor, const nsAString& driverVendor,
304 GfxDeviceFamily* devices, int32_t feature,
305 int32_t featureStatus, VersionComparisonOp op,
306 uint64_t driverVersion, const char* ruleId,
307 const char* suggestedVersion = nullptr, bool ownDevices = false,
308 bool gpu2 = false);
310 GfxDriverInfo();
311 GfxDriverInfo(const GfxDriverInfo&);
312 ~GfxDriverInfo();
314 OperatingSystem mOperatingSystem;
315 uint32_t mOperatingSystemVersion;
316 ScreenSizeStatus mScreen;
317 BatteryStatus mBattery;
318 nsString mWindowProtocol;
320 nsString mAdapterVendor;
321 nsString mDriverVendor;
323 const GfxDeviceFamily* mDevices;
325 // Whether the mDevices array should be deleted when this structure is
326 // deallocated. False by default.
327 bool mDeleteDevices;
329 /* A feature from nsIGfxInfo, or a wildcard set of features */
330 int32_t mFeature;
331 /* Block all features */
332 static constexpr int32_t allFeatures = -1;
333 /* Block all features not permitted by OnlyAllowFeatureOnKnownConfig */
334 static constexpr int32_t optionalFeatures = -2;
336 /* A feature status from nsIGfxInfo */
337 int32_t mFeatureStatus;
339 VersionComparisonOp mComparisonOp;
341 /* versions are assumed to be A.B.C.D packed as 0xAAAABBBBCCCCDDDD */
342 uint64_t mDriverVersion;
343 uint64_t mDriverVersionMax;
344 static constexpr uint64_t allDriverVersions = ~(uint64_t(0));
346 const char* mSuggestedVersion;
347 nsCString mRuleId;
349 static const GfxDeviceFamily* GetDeviceFamily(DeviceFamily id);
350 static GfxDeviceFamily*
351 sDeviceFamilies[static_cast<size_t>(DeviceFamily::Max)];
353 static const nsAString& GetWindowProtocol(WindowProtocol id);
354 static nsString* sWindowProtocol[static_cast<size_t>(WindowProtocol::Max)];
356 static const nsAString& GetDeviceVendor(DeviceVendor id);
357 static const nsAString& GetDeviceVendor(DeviceFamily id);
358 static nsString* sDeviceVendors[static_cast<size_t>(DeviceVendor::Max)];
360 static const nsAString& GetDriverVendor(DriverVendor id);
361 static nsString* sDriverVendors[static_cast<size_t>(DriverVendor::Max)];
363 nsString mModel, mHardware, mProduct, mManufacturer;
365 bool mGpu2;
368 inline uint64_t DriverVersion(uint32_t a, uint32_t b, uint32_t c, uint32_t d) {
369 return (uint64_t(a) << 48) | (uint64_t(b) << 32) | (uint64_t(c) << 16) |
370 uint64_t(d);
373 inline uint64_t V(uint32_t a, uint32_t b, uint32_t c, uint32_t d) {
374 #ifdef XP_WIN
375 // We make sure every driver number is padded by 0s, this will allow us the
376 // easiest 'compare as if decimals' approach. See ParseDriverVersion for a
377 // more extensive explanation of this approach.
378 while (b > 0 && b < 1000) {
379 b *= 10;
381 while (c > 0 && c < 1000) {
382 c *= 10;
384 while (d > 0 && d < 1000) {
385 d *= 10;
387 #endif
388 return DriverVersion(a, b, c, d);
391 // All destination string storage needs to have at least 5 bytes available.
392 inline bool SplitDriverVersion(const char* aSource, char* aAStr, char* aBStr,
393 char* aCStr, char* aDStr) {
394 // sscanf doesn't do what we want here to we parse this manually.
395 int len = strlen(aSource);
397 // This "4" is hardcoded in a few places, including once as a 3.
398 char* dest[4] = {aAStr, aBStr, aCStr, aDStr};
399 unsigned destIdx = 0;
400 unsigned destPos = 0;
402 for (int i = 0; i < len; i++) {
403 if (destIdx >= 4) {
404 // Invalid format found. Ensure we don't access dest beyond bounds.
405 return false;
408 if (aSource[i] == '.') {
409 MOZ_ASSERT(destIdx < 4 && destPos <= 4);
410 dest[destIdx++][destPos] = 0;
411 destPos = 0;
412 continue;
415 if (destPos > 3) {
416 // Ignore more than 4 chars. Ensure we never access dest[destIdx]
417 // beyond its bounds.
418 continue;
421 MOZ_ASSERT(destIdx < 4 && destPos < 4);
422 dest[destIdx][destPos++] = aSource[i];
425 // Take care of the trailing period
426 if (destIdx >= 4) {
427 return false;
430 // Add last terminator.
431 MOZ_ASSERT(destIdx < 4 && destPos <= 4);
432 dest[destIdx][destPos] = 0;
433 for (int unusedDestIdx = destIdx + 1; unusedDestIdx < 4; unusedDestIdx++) {
434 dest[unusedDestIdx][0] = 0;
437 if (destIdx != 3) {
438 return false;
440 return true;
443 // This allows us to pad driver version 'substrings' with 0s, this
444 // effectively allows us to treat the version numbers as 'decimals'. This is
445 // a little strange but this method seems to do the right thing for all
446 // different vendor's driver strings. i.e. .98 will become 9800, which is
447 // larger than .978 which would become 9780.
448 inline void PadDriverDecimal(char* aString) {
449 for (int i = 0; i < 4; i++) {
450 if (!aString[i]) {
451 for (int c = i; c < 4; c++) {
452 aString[c] = '0';
454 break;
457 aString[4] = 0;
460 inline bool ParseDriverVersion(const nsAString& aVersion,
461 uint64_t* aNumericVersion) {
462 *aNumericVersion = 0;
464 #ifndef ANDROID
465 int a, b, c, d;
466 char aStr[8], bStr[8], cStr[8], dStr[8];
467 /* honestly, why do I even bother */
468 if (!SplitDriverVersion(NS_LossyConvertUTF16toASCII(aVersion).get(), aStr,
469 bStr, cStr, dStr))
470 return false;
472 # ifdef XP_WIN
473 PadDriverDecimal(bStr);
474 PadDriverDecimal(cStr);
475 PadDriverDecimal(dStr);
476 # endif
478 a = atoi(aStr);
479 b = atoi(bStr);
480 c = atoi(cStr);
481 d = atoi(dStr);
483 if (a < 0 || a > 0xffff) return false;
484 if (b < 0 || b > 0xffff) return false;
485 if (c < 0 || c > 0xffff) return false;
486 if (d < 0 || d > 0xffff) return false;
488 *aNumericVersion = DriverVersion(a, b, c, d);
489 #else
490 // Can't use aVersion.ToInteger() because that's not compiled into our code
491 // unless we have XPCOM_GLUE_AVOID_NSPR disabled.
492 *aNumericVersion = atoi(NS_LossyConvertUTF16toASCII(aVersion).get());
493 #endif
494 MOZ_ASSERT(*aNumericVersion != GfxDriverInfo::allDriverVersions);
495 return true;
498 } // namespace widget
499 } // namespace mozilla
501 #endif /*__mozilla_widget_GfxDriverInfo_h__ */