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__
11 // Macros for adding a blocklist item to the static list.
12 #define APPEND_TO_DRIVER_BLOCKLIST(os, vendor, devices, feature, \
13 featureStatus, driverComparator, \
14 driverVersion, ruleId, suggestedVersion) \
15 sDriverInfo->AppendElement(GfxDriverInfo( \
16 os, vendor, devices, feature, featureStatus, driverComparator, \
17 driverVersion, ruleId, suggestedVersion))
18 #define APPEND_TO_DRIVER_BLOCKLIST2(os, vendor, devices, feature, \
19 featureStatus, driverComparator, \
20 driverVersion, ruleId) \
21 sDriverInfo->AppendElement(GfxDriverInfo(os, vendor, devices, feature, \
22 featureStatus, driverComparator, \
23 driverVersion, ruleId))
25 #define APPEND_TO_DRIVER_BLOCKLIST_RANGE( \
26 os, vendor, devices, feature, featureStatus, driverComparator, \
27 driverVersion, driverVersionMax, ruleId, suggestedVersion) \
29 MOZ_ASSERT(driverComparator == DRIVER_BETWEEN_EXCLUSIVE || \
30 driverComparator == DRIVER_BETWEEN_INCLUSIVE || \
31 driverComparator == DRIVER_BETWEEN_INCLUSIVE_START); \
32 GfxDriverInfo info(os, vendor, devices, feature, featureStatus, \
33 driverComparator, driverVersion, ruleId, \
35 info.mDriverVersionMax = driverVersionMax; \
36 sDriverInfo->AppendElement(info); \
39 #define APPEND_TO_DRIVER_BLOCKLIST_RANGE_GPU2( \
40 os, vendor, devices, feature, featureStatus, driverComparator, \
41 driverVersion, driverVersionMax, ruleId, suggestedVersion) \
43 MOZ_ASSERT(driverComparator == DRIVER_BETWEEN_EXCLUSIVE || \
44 driverComparator == DRIVER_BETWEEN_INCLUSIVE || \
45 driverComparator == DRIVER_BETWEEN_INCLUSIVE_START); \
46 GfxDriverInfo info(os, vendor, devices, feature, featureStatus, \
47 driverComparator, driverVersion, ruleId, \
48 suggestedVersion, false, true); \
49 info.mDriverVersionMax = driverVersionMax; \
50 sDriverInfo->AppendElement(info); \
56 enum class OperatingSystem
{
81 enum VersionComparisonOp
{
82 DRIVER_LESS_THAN
, // driver < version
83 DRIVER_BUILD_ID_LESS_THAN
, // driver build id < version
84 DRIVER_LESS_THAN_OR_EQUAL
, // driver <= version
85 DRIVER_BUILD_ID_LESS_THAN_OR_EQUAL
, // driver build id <= version
86 DRIVER_GREATER_THAN
, // driver > version
87 DRIVER_GREATER_THAN_OR_EQUAL
, // driver >= version
88 DRIVER_EQUAL
, // driver == version
89 DRIVER_NOT_EQUAL
, // driver != version
90 DRIVER_BETWEEN_EXCLUSIVE
, // driver > version && driver < versionMax
91 DRIVER_BETWEEN_INCLUSIVE
, // driver >= version && driver <= versionMax
92 DRIVER_BETWEEN_INCLUSIVE_START
, // driver >= version && driver < versionMax
93 DRIVER_COMPARISON_IGNORED
103 IntelHDGraphicsToSandyBridge
,
104 IntelHDGraphicsToHaswell
,
106 IntelMobileHDGraphics
,
107 NvidiaBlockD3D9Layers
,
117 NvidiaBlockWebRender
,
122 VendorAll
, // There is an assumption that this is the first enum
133 /* Array of devices to match, or an empty array for all devices */
134 typedef nsTArray
<nsString
> GfxDeviceFamily
;
136 struct GfxDriverInfo
{
137 // If |ownDevices| is true, you are transferring ownership of the devices
138 // array, and it will be deleted when this GfxDriverInfo is destroyed.
139 GfxDriverInfo(OperatingSystem os
, nsAString
&vendor
, GfxDeviceFamily
*devices
,
140 int32_t feature
, int32_t featureStatus
, VersionComparisonOp op
,
141 uint64_t driverVersion
, const char *ruleId
,
142 const char *suggestedVersion
= nullptr, bool ownDevices
= false,
146 GfxDriverInfo(const GfxDriverInfo
&);
149 OperatingSystem mOperatingSystem
;
150 uint32_t mOperatingSystemVersion
;
152 nsString mAdapterVendor
;
154 static GfxDeviceFamily
*const allDevices
;
155 GfxDeviceFamily
*mDevices
;
157 // Whether the mDevices array should be deleted when this structure is
158 // deallocated. False by default.
161 /* A feature from nsIGfxInfo, or all features */
163 static int32_t allFeatures
;
165 /* A feature status from nsIGfxInfo */
166 int32_t mFeatureStatus
;
168 VersionComparisonOp mComparisonOp
;
170 /* versions are assumed to be A.B.C.D packed as 0xAAAABBBBCCCCDDDD */
171 uint64_t mDriverVersion
;
172 uint64_t mDriverVersionMax
;
173 static uint64_t allDriverVersions
;
175 const char *mSuggestedVersion
;
178 static const GfxDeviceFamily
*GetDeviceFamily(DeviceFamily id
);
179 static GfxDeviceFamily
*sDeviceFamilies
[DeviceFamilyMax
];
181 static const nsAString
&GetDeviceVendor(DeviceVendor id
);
182 static nsAString
*sDeviceVendors
[DeviceVendorMax
];
184 nsString mModel
, mHardware
, mProduct
, mManufacturer
;
189 #define GFX_DRIVER_VERSION(a, b, c, d) \
190 ((uint64_t(a) << 48) | (uint64_t(b) << 32) | (uint64_t(c) << 16) | \
193 inline uint64_t V(uint32_t a
, uint32_t b
, uint32_t c
, uint32_t d
) {
194 // We make sure every driver number is padded by 0s, this will allow us the
195 // easiest 'compare as if decimals' approach. See ParseDriverVersion for a
196 // more extensive explanation of this approach.
197 while (b
> 0 && b
< 1000) {
200 while (c
> 0 && c
< 1000) {
203 while (d
> 0 && d
< 1000) {
206 return GFX_DRIVER_VERSION(a
, b
, c
, d
);
209 // All destination string storage needs to have at least 5 bytes available.
210 inline bool SplitDriverVersion(const char *aSource
, char *aAStr
, char *aBStr
,
211 char *aCStr
, char *aDStr
) {
212 // sscanf doesn't do what we want here to we parse this manually.
213 int len
= strlen(aSource
);
215 // This "4" is hardcoded in a few places, including once as a 3.
216 char *dest
[4] = {aAStr
, aBStr
, aCStr
, aDStr
};
217 unsigned destIdx
= 0;
218 unsigned destPos
= 0;
220 for (int i
= 0; i
< len
; i
++) {
222 // Invalid format found. Ensure we don't access dest beyond bounds.
226 if (aSource
[i
] == '.') {
227 MOZ_ASSERT(destIdx
< 4 && destPos
<= 4);
228 dest
[destIdx
++][destPos
] = 0;
234 // Ignore more than 4 chars. Ensure we never access dest[destIdx]
235 // beyond its bounds.
239 MOZ_ASSERT(destIdx
< 4 && destPos
< 4);
240 dest
[destIdx
][destPos
++] = aSource
[i
];
243 // Take care of the trailing period
248 // Add last terminator.
249 MOZ_ASSERT(destIdx
< 4 && destPos
<= 4);
250 dest
[destIdx
][destPos
] = 0;
258 // This allows us to pad driver version 'substrings' with 0s, this
259 // effectively allows us to treat the version numbers as 'decimals'. This is
260 // a little strange but this method seems to do the right thing for all
261 // different vendor's driver strings. i.e. .98 will become 9800, which is
262 // larger than .978 which would become 9780.
263 inline void PadDriverDecimal(char *aString
) {
264 for (int i
= 0; i
< 4; i
++) {
266 for (int c
= i
; c
< 4; c
++) {
275 inline bool ParseDriverVersion(const nsAString
&aVersion
,
276 uint64_t *aNumericVersion
) {
277 *aNumericVersion
= 0;
281 char aStr
[8], bStr
[8], cStr
[8], dStr
[8];
282 /* honestly, why do I even bother */
283 if (!SplitDriverVersion(NS_LossyConvertUTF16toASCII(aVersion
).get(), aStr
,
287 PadDriverDecimal(bStr
);
288 PadDriverDecimal(cStr
);
289 PadDriverDecimal(dStr
);
296 if (a
< 0 || a
> 0xffff) return false;
297 if (b
< 0 || b
> 0xffff) return false;
298 if (c
< 0 || c
> 0xffff) return false;
299 if (d
< 0 || d
> 0xffff) return false;
301 *aNumericVersion
= GFX_DRIVER_VERSION(a
, b
, c
, d
);
302 MOZ_ASSERT(*aNumericVersion
!= GfxDriverInfo::allDriverVersions
);
304 #elif defined(ANDROID)
305 // Can't use aVersion.ToInteger() because that's not compiled into our code
306 // unless we have XPCOM_GLUE_AVOID_NSPR disabled.
307 *aNumericVersion
= atoi(NS_LossyConvertUTF16toASCII(aVersion
).get());
308 MOZ_ASSERT(*aNumericVersion
!= GfxDriverInfo::allDriverVersions
);
315 } // namespace widget
316 } // namespace mozilla
318 #endif /*__mozilla_widget_GfxDriverInfo_h__ */