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 "mozilla/ArrayUtils.h" // ArrayLength
12 // Macros for adding a blocklist item to the static list.
13 #define APPEND_TO_DRIVER_BLOCKLIST(os, vendor, devices, feature, featureStatus, driverComparator, driverVersion, suggestedVersion) \
14 mDriverInfo->AppendElement(GfxDriverInfo(os, vendor, devices, feature, featureStatus, driverComparator, driverVersion, suggestedVersion))
15 #define APPEND_TO_DRIVER_BLOCKLIST2(os, vendor, devices, feature, featureStatus, driverComparator, driverVersion) \
16 mDriverInfo->AppendElement(GfxDriverInfo(os, vendor, devices, feature, featureStatus, driverComparator, driverVersion))
18 #define APPEND_TO_DRIVER_BLOCKLIST_RANGE(os, vendor, devices, feature, featureStatus, driverComparator, driverVersion, driverVersionMax, suggestedVersion) \
20 MOZ_ASSERT(driverComparator == DRIVER_BETWEEN_EXCLUSIVE || \
21 driverComparator == DRIVER_BETWEEN_INCLUSIVE || \
22 driverComparator == DRIVER_BETWEEN_INCLUSIVE_START); \
23 GfxDriverInfo info(os, vendor, devices, feature, featureStatus, driverComparator, driverVersion, suggestedVersion); \
24 info.mDriverVersionMax = driverVersionMax; \
25 mDriverInfo->AppendElement(info); \
31 enum OperatingSystem
{
32 DRIVER_OS_UNKNOWN
= 0,
34 DRIVER_OS_WINDOWS_SERVER_2003
,
35 DRIVER_OS_WINDOWS_VISTA
,
38 DRIVER_OS_WINDOWS_8_1
,
48 enum VersionComparisonOp
{
49 DRIVER_LESS_THAN
, // driver < version
50 DRIVER_LESS_THAN_OR_EQUAL
, // driver <= version
51 DRIVER_GREATER_THAN
, // driver > version
52 DRIVER_GREATER_THAN_OR_EQUAL
, // driver >= version
53 DRIVER_EQUAL
, // driver == version
54 DRIVER_NOT_EQUAL
, // driver != version
55 DRIVER_BETWEEN_EXCLUSIVE
, // driver > version && driver < versionMax
56 DRIVER_BETWEEN_INCLUSIVE
, // driver >= version && driver <= versionMax
57 DRIVER_BETWEEN_INCLUSIVE_START
, // driver >= version && driver < versionMax
58 DRIVER_COMPARISON_IGNORED
69 IntelMobileHDGraphics
,
70 NvidiaBlockD3D9Layers
,
87 /* Array of devices to match, or an empty array for all devices */
88 typedef nsTArray
<nsString
> GfxDeviceFamily
;
92 // If |ownDevices| is true, you are transferring ownership of the devices
93 // array, and it will be deleted when this GfxDriverInfo is destroyed.
94 GfxDriverInfo(OperatingSystem os
, nsAString
& vendor
, GfxDeviceFamily
* devices
,
95 int32_t feature
, int32_t featureStatus
, VersionComparisonOp op
,
96 uint64_t driverVersion
, const char *suggestedVersion
= nullptr,
97 bool ownDevices
= false);
100 GfxDriverInfo(const GfxDriverInfo
&);
103 OperatingSystem mOperatingSystem
;
104 uint32_t mOperatingSystemVersion
;
106 nsString mAdapterVendor
;
108 static GfxDeviceFamily
* const allDevices
;
109 GfxDeviceFamily
* mDevices
;
111 // Whether the mDevices array should be deleted when this structure is
112 // deallocated. False by default.
115 /* A feature from nsIGfxInfo, or all features */
117 static int32_t allFeatures
;
119 /* A feature status from nsIGfxInfo */
120 int32_t mFeatureStatus
;
122 VersionComparisonOp mComparisonOp
;
124 /* versions are assumed to be A.B.C.D packed as 0xAAAABBBBCCCCDDDD */
125 uint64_t mDriverVersion
;
126 uint64_t mDriverVersionMax
;
127 static uint64_t allDriverVersions
;
129 const char *mSuggestedVersion
;
131 static const GfxDeviceFamily
* GetDeviceFamily(DeviceFamily id
);
132 static GfxDeviceFamily
* mDeviceFamilies
[DeviceFamilyMax
];
134 static const nsAString
& GetDeviceVendor(DeviceVendor id
);
135 static nsAString
* mDeviceVendors
[DeviceVendorMax
];
137 nsString mModel
, mHardware
, mProduct
, mManufacturer
;
140 #define GFX_DRIVER_VERSION(a,b,c,d) \
141 ((uint64_t(a)<<48) | (uint64_t(b)<<32) | (uint64_t(c)<<16) | uint64_t(d))
144 V(uint32_t a
, uint32_t b
, uint32_t c
, uint32_t d
)
146 // We make sure every driver number is padded by 0s, this will allow us the
147 // easiest 'compare as if decimals' approach. See ParseDriverVersion for a
148 // more extensive explanation of this approach.
149 while (b
> 0 && b
< 1000) {
152 while (c
> 0 && c
< 1000) {
155 while (d
> 0 && d
< 1000) {
158 return GFX_DRIVER_VERSION(a
, b
, c
, d
);
161 // All destination string storage needs to have at least 5 bytes available.
162 inline bool SplitDriverVersion(const char *aSource
, char *aAStr
, char *aBStr
, char *aCStr
, char *aDStr
)
164 // sscanf doesn't do what we want here to we parse this manually.
165 int len
= strlen(aSource
);
166 char *dest
[4] = { aAStr
, aBStr
, aCStr
, aDStr
};
167 unsigned destIdx
= 0;
168 unsigned destPos
= 0;
170 for (int i
= 0; i
< len
; i
++) {
171 if (destIdx
> ArrayLength(dest
)) {
172 // Invalid format found. Ensure we don't access dest beyond bounds.
176 if (aSource
[i
] == '.') {
177 dest
[destIdx
++][destPos
] = 0;
183 // Ignore more than 4 chars. Ensure we never access dest[destIdx]
184 // beyond its bounds.
188 dest
[destIdx
][destPos
++] = aSource
[i
];
191 // Add last terminator.
192 dest
[destIdx
][destPos
] = 0;
194 if (destIdx
!= ArrayLength(dest
) - 1) {
200 // This allows us to pad driver version 'substrings' with 0s, this
201 // effectively allows us to treat the version numbers as 'decimals'. This is
202 // a little strange but this method seems to do the right thing for all
203 // different vendor's driver strings. i.e. .98 will become 9800, which is
204 // larger than .978 which would become 9780.
205 inline void PadDriverDecimal(char *aString
)
207 for (int i
= 0; i
< 4; i
++) {
209 for (int c
= i
; c
< 4; c
++) {
219 ParseDriverVersion(const nsAString
& aVersion
, uint64_t *aNumericVersion
)
221 *aNumericVersion
= 0;
225 char aStr
[8], bStr
[8], cStr
[8], dStr
[8];
226 /* honestly, why do I even bother */
227 if (!SplitDriverVersion(NS_LossyConvertUTF16toASCII(aVersion
).get(), aStr
, bStr
, cStr
, dStr
))
230 PadDriverDecimal(bStr
);
231 PadDriverDecimal(cStr
);
232 PadDriverDecimal(dStr
);
239 if (a
< 0 || a
> 0xffff) return false;
240 if (b
< 0 || b
> 0xffff) return false;
241 if (c
< 0 || c
> 0xffff) return false;
242 if (d
< 0 || d
> 0xffff) return false;
244 *aNumericVersion
= GFX_DRIVER_VERSION(a
, b
, c
, d
);
246 #elif defined(ANDROID)
247 // Can't use aVersion.ToInteger() because that's not compiled into our code
248 // unless we have XPCOM_GLUE_AVOID_NSPR disabled.
249 *aNumericVersion
= atoi(NS_LossyConvertUTF16toASCII(aVersion
).get());
259 #endif /*__mozilla_widget_GfxDriverInfo_h__ */