Bug 1631735 Part 1: Make nsCocoaWindow animated transitions asynchronous and atomic...
[gecko.git] / widget / GfxDriverInfo.h
blob9141fd44f9041e1954635035e0a445b23625e73b
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 IntelHD520,
182 IntelMobileHDGraphics,
183 NvidiaBlockD3D9Layers,
184 RadeonX1000,
185 RadeonCaicos,
186 RadeonBlockZeroVideoCopy,
187 Geforce7300GT,
188 Nvidia310M,
189 Nvidia8800GTS,
190 Bug1137716,
191 Bug1116812,
192 Bug1155608,
193 Bug1207665,
194 Bug1447141,
195 AmdR600,
196 IntelWebRenderBlocked,
197 NvidiaWebRenderBlocked,
202 enum class DeviceVendor : uint8_t {
203 All, // There is an assumption that this is the first enum
204 Intel,
205 NVIDIA,
206 ATI,
207 Microsoft,
208 Parallels,
209 VMWare,
210 VirtualBox,
211 Qualcomm,
212 MicrosoftBasic,
213 MicrosoftHyperV,
214 Apple,
215 Amazon,
220 enum DriverVendor : uint8_t {
221 All, // There is an assumption that this is the first enum
222 // Wildcard for all Mesa drivers.
223 MesaAll,
224 // Note that the following list of Mesa drivers is not comprehensive; we pull
225 // the DRI driver at runtime. These drivers are provided for convenience when
226 // populating the local blocklist.
227 MesaLLVMPipe,
228 MesaSoftPipe,
229 MesaSWRast,
230 MesaSWUnknown,
231 // AMD
232 MesaR600,
233 // Nouveau: Open-source nvidia
234 MesaNouveau,
235 // A generic ID to be provided when we can't determine the DRI driver on Mesa.
236 MesaUnknown,
237 // Wildcard for all non-Mesa drivers.
238 NonMesaAll,
239 // Wildcard for all hardware Mesa drivers.
240 HardwareMesaAll,
241 // Wildcard for all software Mesa drivers.
242 SoftwareMesaAll,
243 // Wildcard for all non-Intel/NVIDIA/ATI Mesa drivers.
244 MesaNonIntelNvidiaAtiAll,
249 enum class WindowProtocol : uint8_t {
250 All, // There is an assumption that this is the first enum
251 X11,
252 XWayland,
253 Wayland,
254 WaylandDRM,
255 // Wildcard for all Wayland variants, excluding XWayland.
256 WaylandAll,
257 // Wildcard for all X11 variants, including XWayland.
258 X11All,
262 enum class BatteryStatus : uint8_t { All, Present, None };
264 enum class ScreenSizeStatus : uint8_t {
265 All,
266 Small, // <= 1900x1200
267 SmallAndMedium, // <= 3440x1440
268 Medium, // <= 3440x1440 && > 1900x1200
269 MediumAndLarge, // >1900x1200
270 Large // > 3440x1440
273 /* Array of devices to match, or an empty array for all devices */
274 class GfxDeviceFamily final {
275 public:
276 GfxDeviceFamily() = default;
278 void Append(const nsAString& aDeviceId);
279 void AppendRange(int32_t aBeginDeviceId, int32_t aEndDeviceId);
281 bool IsEmpty() const { return mIds.IsEmpty() && mRanges.IsEmpty(); }
283 nsresult Contains(nsAString& aDeviceId) const;
285 private:
286 struct DeviceRange {
287 int32_t mBegin;
288 int32_t mEnd;
291 CopyableTArray<nsString> mIds;
292 CopyableTArray<DeviceRange> mRanges;
295 struct GfxDriverInfo {
296 // If |ownDevices| is true, you are transferring ownership of the devices
297 // array, and it will be deleted when this GfxDriverInfo is destroyed.
298 GfxDriverInfo(OperatingSystem os, ScreenSizeStatus aScreen,
299 BatteryStatus aBattery, const nsAString& windowProtocol,
300 const nsAString& vendor, const nsAString& driverVendor,
301 GfxDeviceFamily* devices, int32_t feature,
302 int32_t featureStatus, VersionComparisonOp op,
303 uint64_t driverVersion, const char* ruleId,
304 const char* suggestedVersion = nullptr, bool ownDevices = false,
305 bool gpu2 = false);
307 GfxDriverInfo();
308 GfxDriverInfo(const GfxDriverInfo&);
309 ~GfxDriverInfo();
311 OperatingSystem mOperatingSystem;
312 uint32_t mOperatingSystemVersion;
313 ScreenSizeStatus mScreen;
314 BatteryStatus mBattery;
315 nsString mWindowProtocol;
317 nsString mAdapterVendor;
318 nsString mDriverVendor;
320 const GfxDeviceFamily* mDevices;
322 // Whether the mDevices array should be deleted when this structure is
323 // deallocated. False by default.
324 bool mDeleteDevices;
326 /* A feature from nsIGfxInfo, or all features */
327 int32_t mFeature;
328 static int32_t allFeatures;
330 /* A feature status from nsIGfxInfo */
331 int32_t mFeatureStatus;
333 VersionComparisonOp mComparisonOp;
335 /* versions are assumed to be A.B.C.D packed as 0xAAAABBBBCCCCDDDD */
336 uint64_t mDriverVersion;
337 uint64_t mDriverVersionMax;
338 static uint64_t allDriverVersions;
340 const char* mSuggestedVersion;
341 nsCString mRuleId;
343 static const GfxDeviceFamily* GetDeviceFamily(DeviceFamily id);
344 static GfxDeviceFamily*
345 sDeviceFamilies[static_cast<size_t>(DeviceFamily::Max)];
347 static const nsAString& GetWindowProtocol(WindowProtocol id);
348 static nsAString* sWindowProtocol[static_cast<size_t>(WindowProtocol::Max)];
350 static const nsAString& GetDeviceVendor(DeviceVendor id);
351 static const nsAString& GetDeviceVendor(DeviceFamily id);
352 static nsAString* sDeviceVendors[static_cast<size_t>(DeviceVendor::Max)];
354 static const nsAString& GetDriverVendor(DriverVendor id);
355 static nsAString* sDriverVendors[static_cast<size_t>(DriverVendor::Max)];
357 nsString mModel, mHardware, mProduct, mManufacturer;
359 bool mGpu2;
362 inline uint64_t DriverVersion(uint32_t a, uint32_t b, uint32_t c, uint32_t d) {
363 return (uint64_t(a) << 48) | (uint64_t(b) << 32) | (uint64_t(c) << 16) |
364 uint64_t(d);
367 inline uint64_t V(uint32_t a, uint32_t b, uint32_t c, uint32_t d) {
368 #ifdef XP_WIN
369 // We make sure every driver number is padded by 0s, this will allow us the
370 // easiest 'compare as if decimals' approach. See ParseDriverVersion for a
371 // more extensive explanation of this approach.
372 while (b > 0 && b < 1000) {
373 b *= 10;
375 while (c > 0 && c < 1000) {
376 c *= 10;
378 while (d > 0 && d < 1000) {
379 d *= 10;
381 #endif
382 return DriverVersion(a, b, c, d);
385 // All destination string storage needs to have at least 5 bytes available.
386 inline bool SplitDriverVersion(const char* aSource, char* aAStr, char* aBStr,
387 char* aCStr, char* aDStr) {
388 // sscanf doesn't do what we want here to we parse this manually.
389 int len = strlen(aSource);
391 // This "4" is hardcoded in a few places, including once as a 3.
392 char* dest[4] = {aAStr, aBStr, aCStr, aDStr};
393 unsigned destIdx = 0;
394 unsigned destPos = 0;
396 for (int i = 0; i < len; i++) {
397 if (destIdx >= 4) {
398 // Invalid format found. Ensure we don't access dest beyond bounds.
399 return false;
402 if (aSource[i] == '.') {
403 MOZ_ASSERT(destIdx < 4 && destPos <= 4);
404 dest[destIdx++][destPos] = 0;
405 destPos = 0;
406 continue;
409 if (destPos > 3) {
410 // Ignore more than 4 chars. Ensure we never access dest[destIdx]
411 // beyond its bounds.
412 continue;
415 MOZ_ASSERT(destIdx < 4 && destPos < 4);
416 dest[destIdx][destPos++] = aSource[i];
419 // Take care of the trailing period
420 if (destIdx >= 4) {
421 return false;
424 // Add last terminator.
425 MOZ_ASSERT(destIdx < 4 && destPos <= 4);
426 dest[destIdx][destPos] = 0;
427 for (int unusedDestIdx = destIdx + 1; unusedDestIdx < 4; unusedDestIdx++) {
428 dest[unusedDestIdx][0] = 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 #ifndef ANDROID
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 # ifdef XP_WIN
467 PadDriverDecimal(bStr);
468 PadDriverDecimal(cStr);
469 PadDriverDecimal(dStr);
470 # endif
472 a = atoi(aStr);
473 b = atoi(bStr);
474 c = atoi(cStr);
475 d = atoi(dStr);
477 if (a < 0 || a > 0xffff) return false;
478 if (b < 0 || b > 0xffff) return false;
479 if (c < 0 || c > 0xffff) return false;
480 if (d < 0 || d > 0xffff) return false;
482 *aNumericVersion = DriverVersion(a, b, c, d);
483 #else
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 #endif
488 MOZ_ASSERT(*aNumericVersion != GfxDriverInfo::allDriverVersions);
489 return true;
492 } // namespace widget
493 } // namespace mozilla
495 #endif /*__mozilla_widget_GfxDriverInfo_h__ */