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__
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
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, \
29 #define APPEND_TO_DRIVER_BLOCKLIST(os, devices, feature, featureStatus, \
30 driverComparator, driverVersion, ruleId, \
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, \
60 MOZ_ASSERT((driverComparator) == DRIVER_BETWEEN_EXCLUSIVE || \
61 (driverComparator) == DRIVER_BETWEEN_INCLUSIVE || \
62 (driverComparator) == DRIVER_BETWEEN_INCLUSIVE_START); \
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, \
71 info.mDriverVersionMax = driverVersionMax; \
72 sDriverInfo->AppendElement(info); \
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, \
88 MOZ_ASSERT((driverComparator) == DRIVER_BETWEEN_EXCLUSIVE || \
89 (driverComparator) == DRIVER_BETWEEN_INCLUSIVE || \
90 (driverComparator) == DRIVER_BETWEEN_INCLUSIVE_START); \
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); \
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)
114 enum class OperatingSystem
: uint8_t {
116 #define GFXINFO_OS(id, name) id,
117 #include "mozilla/widget/GfxInfoOperatingSystemDefs.h"
122 enum VersionComparisonOp
{
123 #define GFXINFO_DRIVER_VERSION_CMP(id) DRIVER_##id,
124 #include "mozilla/widget/GfxInfoDriverVersionCmpDefs.h"
125 #undef GFXINFO_DRIVER_VERSION_CMP
129 enum class DeviceFamily
: uint8_t {
145 IntelHDGraphicsToIvyBridge
,
146 IntelHDGraphicsToSandyBridge
,
153 IntelMobileHDGraphics
,
157 NvidiaBlockD3D9Layers
,
160 RadeonBlockZeroVideoCopy
,
171 IntelWebRenderBlocked
,
172 NvidiaWebRenderBlocked
,
177 enum class DeviceVendor
: uint8_t {
178 #define GFXINFO_DEVICE_VENDOR(id, name) id,
179 #include "mozilla/widget/GfxInfoDeviceVendorDefs.h"
180 #undef GFXINFO_DEVICE_VENDOR
184 enum DriverVendor
: uint8_t {
185 #define GFXINFO_DRIVER_VENDOR(id, name) id,
186 #include "mozilla/widget/GfxInfoDriverVendorDefs.h"
187 #undef GFXINFO_DRIVER_VENDOR
191 enum class WindowProtocol
: uint8_t {
192 #define GFXINFO_WINDOW_PROTOCOL(id, name) id,
193 #include "mozilla/widget/GfxInfoWindowProtocolDefs.h"
194 #undef GFXINFO_WINDOW_PROTOCOL
198 enum class BatteryStatus
: uint8_t { All
, Present
, None
};
200 enum class ScreenSizeStatus
: uint8_t {
202 Small
, // <= 1900x1200
203 SmallAndMedium
, // <= 3440x1440
204 Medium
, // <= 3440x1440 && > 1900x1200
205 MediumAndLarge
, // >1900x1200
209 /* Array of devices to match, or an empty array for all devices */
210 class GfxDeviceFamily final
{
212 GfxDeviceFamily() = default;
214 void Append(const nsAString
& aDeviceId
);
215 void AppendRange(int32_t aBeginDeviceId
, int32_t aEndDeviceId
);
217 bool IsEmpty() const { return mIds
.IsEmpty() && mRanges
.IsEmpty(); }
219 nsresult
Contains(nsAString
& aDeviceId
) const;
227 CopyableTArray
<nsString
> mIds
;
228 CopyableTArray
<DeviceRange
> mRanges
;
231 struct GfxDriverInfo
{
232 // If |ownDevices| is true, you are transferring ownership of the devices
233 // array, and it will be deleted when this GfxDriverInfo is destroyed.
234 GfxDriverInfo(OperatingSystem os
, ScreenSizeStatus aScreen
,
235 BatteryStatus aBattery
, const nsAString
& windowProtocol
,
236 const nsAString
& vendor
, const nsAString
& driverVendor
,
237 GfxDeviceFamily
* devices
, int32_t feature
,
238 int32_t featureStatus
, VersionComparisonOp op
,
239 uint64_t driverVersion
, const char* ruleId
,
240 const char* suggestedVersion
= nullptr, bool ownDevices
= false,
244 GfxDriverInfo(const GfxDriverInfo
&);
247 OperatingSystem mOperatingSystem
;
248 uint32_t mOperatingSystemVersion
;
249 ScreenSizeStatus mScreen
;
250 BatteryStatus mBattery
;
251 nsString mWindowProtocol
;
253 nsString mAdapterVendor
;
254 nsString mDriverVendor
;
256 const GfxDeviceFamily
* mDevices
;
258 // Whether the mDevices array should be deleted when this structure is
259 // deallocated. False by default.
262 /* A feature from nsIGfxInfo, or a wildcard set of features */
264 /* Block all features */
265 static constexpr int32_t allFeatures
= -1;
266 /* Block all features not permitted by OnlyAllowFeatureOnKnownConfig */
267 static constexpr int32_t optionalFeatures
= -2;
269 /* A feature status from nsIGfxInfo */
270 int32_t mFeatureStatus
;
272 VersionComparisonOp mComparisonOp
;
274 /* versions are assumed to be A.B.C.D packed as 0xAAAABBBBCCCCDDDD */
275 uint64_t mDriverVersion
;
276 uint64_t mDriverVersionMax
;
277 static constexpr uint64_t allDriverVersions
= ~(uint64_t(0));
279 const char* mSuggestedVersion
;
282 static const GfxDeviceFamily
* GetDeviceFamily(DeviceFamily id
);
283 static GfxDeviceFamily
*
284 sDeviceFamilies
[static_cast<size_t>(DeviceFamily::Max
)];
286 static const nsAString
& GetWindowProtocol(WindowProtocol id
);
287 static nsString
* sWindowProtocol
[static_cast<size_t>(WindowProtocol::Max
)];
289 static const nsAString
& GetDeviceVendor(DeviceVendor id
);
290 static const nsAString
& GetDeviceVendor(DeviceFamily id
);
291 static nsString
* sDeviceVendors
[static_cast<size_t>(DeviceVendor::Max
)];
293 static const nsAString
& GetDriverVendor(DriverVendor id
);
294 static nsString
* sDriverVendors
[static_cast<size_t>(DriverVendor::Max
)];
296 nsString mModel
, mHardware
, mProduct
, mManufacturer
;
301 inline uint64_t DriverVersion(uint32_t a
, uint32_t b
, uint32_t c
, uint32_t d
) {
302 return (uint64_t(a
) << 48) | (uint64_t(b
) << 32) | (uint64_t(c
) << 16) |
306 inline uint64_t V(uint32_t a
, uint32_t b
, uint32_t c
, uint32_t d
) {
308 // We make sure every driver number is padded by 0s, this will allow us the
309 // easiest 'compare as if decimals' approach. See ParseDriverVersion for a
310 // more extensive explanation of this approach.
311 while (b
> 0 && b
< 1000) {
314 while (c
> 0 && c
< 1000) {
317 while (d
> 0 && d
< 1000) {
321 return DriverVersion(a
, b
, c
, d
);
324 // All destination string storage needs to have at least 5 bytes available.
325 inline bool SplitDriverVersion(const char* aSource
, char* aAStr
, char* aBStr
,
326 char* aCStr
, char* aDStr
) {
327 // sscanf doesn't do what we want here to we parse this manually.
328 int len
= strlen(aSource
);
330 // This "4" is hardcoded in a few places, including once as a 3.
331 char* dest
[4] = {aAStr
, aBStr
, aCStr
, aDStr
};
332 unsigned destIdx
= 0;
333 unsigned destPos
= 0;
335 for (int i
= 0; i
< len
; i
++) {
337 // Invalid format found. Ensure we don't access dest beyond bounds.
341 if (aSource
[i
] == '.') {
342 MOZ_ASSERT(destIdx
< 4 && destPos
<= 4);
343 dest
[destIdx
++][destPos
] = 0;
349 // Ignore more than 4 chars. Ensure we never access dest[destIdx]
350 // beyond its bounds.
354 MOZ_ASSERT(destIdx
< 4 && destPos
< 4);
355 dest
[destIdx
][destPos
++] = aSource
[i
];
358 // Take care of the trailing period
363 // Add last terminator.
364 MOZ_ASSERT(destIdx
< 4 && destPos
<= 4);
365 dest
[destIdx
][destPos
] = 0;
366 for (int unusedDestIdx
= destIdx
+ 1; unusedDestIdx
< 4; unusedDestIdx
++) {
367 dest
[unusedDestIdx
][0] = 0;
376 // This allows us to pad driver version 'substrings' with 0s, this
377 // effectively allows us to treat the version numbers as 'decimals'. This is
378 // a little strange but this method seems to do the right thing for all
379 // different vendor's driver strings. i.e. .98 will become 9800, which is
380 // larger than .978 which would become 9780.
381 inline void PadDriverDecimal(char* aString
) {
382 for (int i
= 0; i
< 4; i
++) {
384 for (int c
= i
; c
< 4; c
++) {
393 inline bool ParseDriverVersion(const nsAString
& aVersion
,
394 uint64_t* aNumericVersion
) {
395 *aNumericVersion
= 0;
399 char aStr
[8], bStr
[8], cStr
[8], dStr
[8];
400 /* honestly, why do I even bother */
401 if (!SplitDriverVersion(NS_LossyConvertUTF16toASCII(aVersion
).get(), aStr
,
406 PadDriverDecimal(bStr
);
407 PadDriverDecimal(cStr
);
408 PadDriverDecimal(dStr
);
416 if (a
< 0 || a
> 0xffff) return false;
417 if (b
< 0 || b
> 0xffff) return false;
418 if (c
< 0 || c
> 0xffff) return false;
419 if (d
< 0 || d
> 0xffff) return false;
421 *aNumericVersion
= DriverVersion(a
, b
, c
, d
);
423 // Can't use aVersion.ToInteger() because that's not compiled into our code
424 // unless we have XPCOM_GLUE_AVOID_NSPR disabled.
425 *aNumericVersion
= atoi(NS_LossyConvertUTF16toASCII(aVersion
).get());
427 MOZ_ASSERT(*aNumericVersion
!= GfxDriverInfo::allDriverVersions
);
431 } // namespace widget
432 } // namespace mozilla
434 #endif /*__mozilla_widget_GfxDriverInfo_h__ */