Bug 1614845 [wpt PR 21744] - Revert "[Shape Detection] Use IDL dictionaries for resul...
[gecko.git] / widget / GfxDriverInfo.h
blobd18a80a1ae2743312329bd4f9aba15a31585515f
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. _EXT variants
12 // allow one to specify all available parameters, including those available
13 // only on specific platforms (e.g. desktop environment and driver vendor
14 // for Linux.)
16 #define APPEND_TO_DRIVER_BLOCKLIST_EXT( \
17 os, screen, battery, desktopEnv, windowProtocol, driverVendor, devices, \
18 feature, featureStatus, driverComparator, driverVersion, ruleId, \
19 suggestedVersion) \
20 sDriverInfo->AppendElement(GfxDriverInfo( \
21 os, screen, battery, \
22 (nsAString&)GfxDriverInfo::GetDesktopEnvironment(desktopEnv), \
23 (nsAString&)GfxDriverInfo::GetWindowProtocol(windowProtocol), \
24 (nsAString&)GfxDriverInfo::GetDeviceVendor(devices), \
25 (nsAString&)GfxDriverInfo::GetDriverVendor(driverVendor), \
26 (GfxDeviceFamily*)GfxDriverInfo::GetDeviceFamily(devices), feature, \
27 featureStatus, driverComparator, driverVersion, ruleId, \
28 suggestedVersion))
30 #define APPEND_TO_DRIVER_BLOCKLIST(os, devices, feature, featureStatus, \
31 driverComparator, driverVersion, ruleId, \
32 suggestedVersion) \
33 APPEND_TO_DRIVER_BLOCKLIST_EXT( \
34 os, ScreenSizeStatus::All, BatteryStatus::All, DesktopEnvironment::All, \
35 WindowProtocol::All, DriverVendor::All, devices, feature, featureStatus, \
36 driverComparator, driverVersion, ruleId, suggestedVersion)
38 #define APPEND_TO_DRIVER_BLOCKLIST2_EXT( \
39 os, screen, battery, desktopEnv, windowProtocol, driverVendor, devices, \
40 feature, featureStatus, driverComparator, driverVersion, ruleId) \
41 sDriverInfo->AppendElement(GfxDriverInfo( \
42 os, screen, battery, \
43 (nsAString&)GfxDriverInfo::GetDesktopEnvironment(desktopEnv), \
44 (nsAString&)GfxDriverInfo::GetWindowProtocol(windowProtocol), \
45 (nsAString&)GfxDriverInfo::GetDeviceVendor(devices), \
46 (nsAString&)GfxDriverInfo::GetDriverVendor(driverVendor), \
47 (GfxDeviceFamily*)GfxDriverInfo::GetDeviceFamily(devices), feature, \
48 featureStatus, driverComparator, driverVersion, ruleId))
50 #define APPEND_TO_DRIVER_BLOCKLIST2(os, devices, feature, featureStatus, \
51 driverComparator, driverVersion, ruleId) \
52 APPEND_TO_DRIVER_BLOCKLIST2_EXT( \
53 os, ScreenSizeStatus::All, BatteryStatus::All, DesktopEnvironment::All, \
54 WindowProtocol::All, DriverVendor::All, devices, feature, featureStatus, \
55 driverComparator, driverVersion, ruleId)
57 #define APPEND_TO_DRIVER_BLOCKLIST_RANGE_EXT( \
58 os, screen, battery, desktopEnv, windowProtocol, driverVendor, devices, \
59 feature, featureStatus, driverComparator, driverVersion, driverVersionMax, \
60 ruleId, suggestedVersion) \
61 do { \
62 MOZ_ASSERT((driverComparator) == DRIVER_BETWEEN_EXCLUSIVE || \
63 (driverComparator) == DRIVER_BETWEEN_INCLUSIVE || \
64 (driverComparator) == DRIVER_BETWEEN_INCLUSIVE_START); \
65 GfxDriverInfo info( \
66 os, screen, battery, \
67 (nsAString&)GfxDriverInfo::GetDesktopEnvironment(desktopEnv), \
68 (nsAString&)GfxDriverInfo::GetWindowProtocol(windowProtocol), \
69 (nsAString&)GfxDriverInfo::GetDeviceVendor(devices), \
70 (nsAString&)GfxDriverInfo::GetDriverVendor(driverVendor), \
71 (GfxDeviceFamily*)GfxDriverInfo::GetDeviceFamily(devices), feature, \
72 featureStatus, driverComparator, driverVersion, ruleId, \
73 suggestedVersion); \
74 info.mDriverVersionMax = driverVersionMax; \
75 sDriverInfo->AppendElement(info); \
76 } while (false)
78 #define APPEND_TO_DRIVER_BLOCKLIST_RANGE( \
79 os, devices, feature, featureStatus, driverComparator, driverVersion, \
80 driverVersionMax, ruleId, suggestedVersion) \
81 APPEND_TO_DRIVER_BLOCKLIST_RANGE_EXT( \
82 os, ScreenSizeStatus::All, BatteryStatus::All, DesktopEnvironment::All, \
83 WindowProtocol::All, DriverVendor::All, devices, feature, featureStatus, \
84 driverComparator, driverVersion, driverVersionMax, ruleId, \
85 suggestedVersion)
87 #define APPEND_TO_DRIVER_BLOCKLIST_RANGE_GPU2_EXT( \
88 os, screen, battery, desktopEnv, windowProtocol, driverVendor, devices, \
89 feature, featureStatus, driverComparator, driverVersion, driverVersionMax, \
90 ruleId, suggestedVersion) \
91 do { \
92 MOZ_ASSERT((driverComparator) == DRIVER_BETWEEN_EXCLUSIVE || \
93 (driverComparator) == DRIVER_BETWEEN_INCLUSIVE || \
94 (driverComparator) == DRIVER_BETWEEN_INCLUSIVE_START); \
95 GfxDriverInfo info( \
96 os, screen, battery, \
97 (nsAString&)GfxDriverInfo::GetDesktopEnvironment(desktopEnv), \
98 (nsAString&)GfxDriverInfo::GetWindowProtocol(windowProtocol), \
99 (nsAString&)GfxDriverInfo::GetDeviceVendor(devices), \
100 (nsAString&)GfxDriverInfo::GetDriverVendor(driverVendor), \
101 (GfxDeviceFamily*)GfxDriverInfo::GetDeviceFamily(devices), feature, \
102 featureStatus, driverComparator, driverVersion, ruleId, \
103 suggestedVersion, false, true); \
104 info.mDriverVersionMax = driverVersionMax; \
105 sDriverInfo->AppendElement(info); \
106 } while (false)
108 #define APPEND_TO_DRIVER_BLOCKLIST_RANGE_GPU2( \
109 os, devices, feature, featureStatus, driverComparator, driverVersion, \
110 driverVersionMax, ruleId, suggestedVersion) \
111 APPEND_TO_DRIVER_BLOCKLIST_RANGE_GPU2_EXT( \
112 os, ScreenSizeStatus::All, BatteryStatus::All, DesktopEnvironment::All, \
113 WindowProtocol::All, DriverVendor::All, devices, feature, featureStatus, \
114 driverComparator, driverVersion, driverVersionMax, ruleId, \
115 suggestedVersion)
117 namespace mozilla {
118 namespace widget {
120 enum class OperatingSystem : uint8_t {
121 Unknown,
122 Windows,
123 WindowsXP,
124 WindowsServer2003,
125 WindowsVista,
126 Windows7,
127 Windows8,
128 Windows8_1,
129 Windows10,
130 RecentWindows10,
131 Linux,
132 OSX,
133 OSX10_5,
134 OSX10_6,
135 OSX10_7,
136 OSX10_8,
137 OSX10_9,
138 OSX10_10,
139 OSX10_11,
140 OSX10_12,
141 OSX10_13,
142 OSX10_14,
143 OSX10_15,
144 Android,
148 enum VersionComparisonOp {
149 DRIVER_LESS_THAN, // driver < version
150 DRIVER_BUILD_ID_LESS_THAN, // driver build id < version
151 DRIVER_LESS_THAN_OR_EQUAL, // driver <= version
152 DRIVER_BUILD_ID_LESS_THAN_OR_EQUAL, // driver build id <= version
153 DRIVER_GREATER_THAN, // driver > version
154 DRIVER_GREATER_THAN_OR_EQUAL, // driver >= version
155 DRIVER_EQUAL, // driver == version
156 DRIVER_NOT_EQUAL, // driver != version
157 DRIVER_BETWEEN_EXCLUSIVE, // driver > version && driver < versionMax
158 DRIVER_BETWEEN_INCLUSIVE, // driver >= version && driver <= versionMax
159 DRIVER_BETWEEN_INCLUSIVE_START, // driver >= version && driver < versionMax
160 DRIVER_COMPARISON_IGNORED
163 enum class DeviceFamily : uint8_t {
164 All,
165 IntelAll,
166 NvidiaAll,
167 AtiAll,
168 AmdAll,
169 MicrosoftAll,
170 ParallelsAll,
171 QualcommAll,
172 IntelGMA500,
173 IntelGMA900,
174 IntelGMA950,
175 IntelGMA3150,
176 IntelGMAX3000,
177 IntelGMAX4500HD,
178 IntelHDGraphicsToIvyBridge,
179 IntelHDGraphicsToSandyBridge,
180 IntelHDGraphicsToHaswell,
181 IntelHD3000,
182 IntelHD520,
183 IntelMobileHDGraphics,
184 NvidiaBlockD3D9Layers,
185 RadeonX1000,
186 AmdRadeonCaicos,
187 Geforce7300GT,
188 Nvidia310M,
189 Nvidia8800GTS,
190 Bug1137716,
191 Bug1116812,
192 Bug1155608,
193 Bug1207665,
194 Bug1447141,
195 NvidiaBlockWebRender,
196 NvidiaRolloutWebRender,
197 IntelRolloutWebRender,
198 AtiRolloutWebRender,
203 enum class DeviceVendor : uint8_t {
204 All, // There is an assumption that this is the first enum
205 Intel,
206 NVIDIA,
207 AMD,
208 ATI,
209 Microsoft,
210 Parallels,
211 Qualcomm,
216 enum DriverVendor : uint8_t {
217 All, // There is an assumption that this is the first enum
218 // Wildcard for all Mesa drivers.
219 MesaAll,
220 // Note that the following list of Mesa drivers is not comprehensive; we pull
221 // the DRI driver at runtime. These drivers are provided for convenience when
222 // populating the local blocklist.
223 MesaLLVMPipe,
224 MesaSoftPipe,
225 MesaSWRast,
226 // A generic ID to be provided when we can't determine the DRI driver on Mesa.
227 MesaUnknown,
228 // Wildcard for all non-Mesa drivers.
229 NonMesaAll,
234 enum class DesktopEnvironment : uint8_t {
235 All, // There is an assumption that this is the first enum
236 GNOME,
237 KDE,
238 XFCE,
239 Cinnamon,
240 Enlightenment,
241 LXDE,
242 Openbox,
244 Mate,
245 Unity,
246 Pantheon,
247 LXQT,
248 Deepin,
249 Unknown,
253 enum class WindowProtocol : uint8_t {
254 All, // There is an assumption that this is the first enum
255 X11,
256 Wayland,
257 WaylandDRM,
258 // Wildcard for all Wayland variants.
259 WaylandAll,
263 enum class BatteryStatus : uint8_t { All, Present, None };
265 enum class ScreenSizeStatus : uint8_t {
266 All,
267 Small, // <= 1900x1200
268 SmallAndMedium, // <= 3440x1440
269 Medium, // <= 3440x1440 && > 1900x1200
270 MediumAndLarge, // >1900x1200
271 Large // > 3440x1440
274 /* Array of devices to match, or an empty array for all devices */
275 class GfxDeviceFamily final {
276 public:
277 GfxDeviceFamily() = default;
279 void Append(const nsAString& aDeviceId);
280 void AppendRange(int32_t aBeginDeviceId, int32_t aEndDeviceId);
282 bool IsEmpty() const { return mIds.IsEmpty() && mRanges.IsEmpty(); }
284 nsresult Contains(nsAString& aDeviceId) const;
286 private:
287 struct DeviceRange {
288 int32_t mBegin;
289 int32_t mEnd;
292 nsTArray<nsString> mIds;
293 nsTArray<DeviceRange> mRanges;
296 struct GfxDriverInfo {
297 // If |ownDevices| is true, you are transferring ownership of the devices
298 // array, and it will be deleted when this GfxDriverInfo is destroyed.
299 GfxDriverInfo(OperatingSystem os, ScreenSizeStatus aScreen,
300 BatteryStatus aBattery, const nsAString& desktopEnv,
301 const nsAString& windowProtocol, const nsAString& vendor,
302 const nsAString& driverVendor, GfxDeviceFamily* devices,
303 int32_t feature, int32_t featureStatus, VersionComparisonOp op,
304 uint64_t driverVersion, const char* ruleId,
305 const char* suggestedVersion = nullptr, bool ownDevices = false,
306 bool gpu2 = false);
308 GfxDriverInfo();
309 GfxDriverInfo(const GfxDriverInfo&);
310 ~GfxDriverInfo();
312 OperatingSystem mOperatingSystem;
313 uint32_t mOperatingSystemVersion;
314 ScreenSizeStatus mScreen;
315 BatteryStatus mBattery;
316 nsString mDesktopEnvironment;
317 nsString mWindowProtocol;
319 nsString mAdapterVendor;
320 nsString mDriverVendor;
322 const GfxDeviceFamily* mDevices;
324 // Whether the mDevices array should be deleted when this structure is
325 // deallocated. False by default.
326 bool mDeleteDevices;
328 /* A feature from nsIGfxInfo, or all features */
329 int32_t mFeature;
330 static int32_t allFeatures;
332 /* A feature status from nsIGfxInfo */
333 int32_t mFeatureStatus;
335 VersionComparisonOp mComparisonOp;
337 /* versions are assumed to be A.B.C.D packed as 0xAAAABBBBCCCCDDDD */
338 uint64_t mDriverVersion;
339 uint64_t mDriverVersionMax;
340 static uint64_t allDriverVersions;
342 const char* mSuggestedVersion;
343 nsCString mRuleId;
345 static const GfxDeviceFamily* GetDeviceFamily(DeviceFamily id);
346 static GfxDeviceFamily*
347 sDeviceFamilies[static_cast<size_t>(DeviceFamily::Max)];
349 static const nsAString& GetDesktopEnvironment(DesktopEnvironment id);
350 static nsAString*
351 sDesktopEnvironment[static_cast<size_t>(DesktopEnvironment::Max)];
353 static const nsAString& GetWindowProtocol(WindowProtocol id);
354 static nsAString* sWindowProtocol[static_cast<size_t>(WindowProtocol::Max)];
356 static const nsAString& GetDeviceVendor(DeviceVendor id);
357 static const nsAString& GetDeviceVendor(DeviceFamily id);
358 static nsAString* sDeviceVendors[static_cast<size_t>(DeviceVendor::Max)];
360 static const nsAString& GetDriverVendor(DriverVendor id);
361 static nsAString* sDriverVendors[static_cast<size_t>(DriverVendor::Max)];
363 nsString mModel, mHardware, mProduct, mManufacturer;
365 bool mGpu2;
368 #define GFX_DRIVER_VERSION(a, b, c, d) \
369 ((uint64_t(a) << 48) | (uint64_t(b) << 32) | (uint64_t(c) << 16) | \
370 uint64_t(d))
372 inline uint64_t V(uint32_t a, uint32_t b, uint32_t c, uint32_t d) {
373 // We make sure every driver number is padded by 0s, this will allow us the
374 // easiest 'compare as if decimals' approach. See ParseDriverVersion for a
375 // more extensive explanation of this approach.
376 while (b > 0 && b < 1000) {
377 b *= 10;
379 while (c > 0 && c < 1000) {
380 c *= 10;
382 while (d > 0 && d < 1000) {
383 d *= 10;
385 return GFX_DRIVER_VERSION(a, b, c, d);
388 // All destination string storage needs to have at least 5 bytes available.
389 inline bool SplitDriverVersion(const char* aSource, char* aAStr, char* aBStr,
390 char* aCStr, char* aDStr) {
391 // sscanf doesn't do what we want here to we parse this manually.
392 int len = strlen(aSource);
394 // This "4" is hardcoded in a few places, including once as a 3.
395 char* dest[4] = {aAStr, aBStr, aCStr, aDStr};
396 unsigned destIdx = 0;
397 unsigned destPos = 0;
399 for (int i = 0; i < len; i++) {
400 if (destIdx >= 4) {
401 // Invalid format found. Ensure we don't access dest beyond bounds.
402 return false;
405 if (aSource[i] == '.') {
406 MOZ_ASSERT(destIdx < 4 && destPos <= 4);
407 dest[destIdx++][destPos] = 0;
408 destPos = 0;
409 continue;
412 if (destPos > 3) {
413 // Ignore more than 4 chars. Ensure we never access dest[destIdx]
414 // beyond its bounds.
415 continue;
418 MOZ_ASSERT(destIdx < 4 && destPos < 4);
419 dest[destIdx][destPos++] = aSource[i];
422 // Take care of the trailing period
423 if (destIdx >= 4) {
424 return false;
427 // Add last terminator.
428 MOZ_ASSERT(destIdx < 4 && destPos <= 4);
429 dest[destIdx][destPos] = 0;
431 if (destIdx != 3) {
432 return false;
434 return true;
437 // This allows us to pad driver version 'substrings' with 0s, this
438 // effectively allows us to treat the version numbers as 'decimals'. This is
439 // a little strange but this method seems to do the right thing for all
440 // different vendor's driver strings. i.e. .98 will become 9800, which is
441 // larger than .978 which would become 9780.
442 inline void PadDriverDecimal(char* aString) {
443 for (int i = 0; i < 4; i++) {
444 if (!aString[i]) {
445 for (int c = i; c < 4; c++) {
446 aString[c] = '0';
448 break;
451 aString[4] = 0;
454 inline bool ParseDriverVersion(const nsAString& aVersion,
455 uint64_t* aNumericVersion) {
456 *aNumericVersion = 0;
458 #if defined(XP_WIN) || defined(MOZ_X11)
459 int a, b, c, d;
460 char aStr[8], bStr[8], cStr[8], dStr[8];
461 /* honestly, why do I even bother */
462 if (!SplitDriverVersion(NS_LossyConvertUTF16toASCII(aVersion).get(), aStr,
463 bStr, cStr, dStr))
464 return false;
466 PadDriverDecimal(bStr);
467 PadDriverDecimal(cStr);
468 PadDriverDecimal(dStr);
470 a = atoi(aStr);
471 b = atoi(bStr);
472 c = atoi(cStr);
473 d = atoi(dStr);
475 if (a < 0 || a > 0xffff) return false;
476 if (b < 0 || b > 0xffff) return false;
477 if (c < 0 || c > 0xffff) return false;
478 if (d < 0 || d > 0xffff) return false;
480 *aNumericVersion = GFX_DRIVER_VERSION(a, b, c, d);
481 MOZ_ASSERT(*aNumericVersion != GfxDriverInfo::allDriverVersions);
482 return true;
483 #elif defined(ANDROID)
484 // Can't use aVersion.ToInteger() because that's not compiled into our code
485 // unless we have XPCOM_GLUE_AVOID_NSPR disabled.
486 *aNumericVersion = atoi(NS_LossyConvertUTF16toASCII(aVersion).get());
487 MOZ_ASSERT(*aNumericVersion != GfxDriverInfo::allDriverVersions);
488 return true;
489 #else
490 return false;
491 #endif
494 } // namespace widget
495 } // namespace mozilla
497 #endif /*__mozilla_widget_GfxDriverInfo_h__ */