1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/widget/xpwidgets/GfxDriverInfo.h Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,257 @@ 1.4 +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 1.5 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.6 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.7 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.8 + 1.9 +#ifndef __mozilla_widget_GfxDriverInfo_h__ 1.10 +#define __mozilla_widget_GfxDriverInfo_h__ 1.11 + 1.12 +#include "mozilla/ArrayUtils.h" // ArrayLength 1.13 +#include "nsString.h" 1.14 + 1.15 +// Macros for adding a blocklist item to the static list. 1.16 +#define APPEND_TO_DRIVER_BLOCKLIST(os, vendor, devices, feature, featureStatus, driverComparator, driverVersion, suggestedVersion) \ 1.17 + mDriverInfo->AppendElement(GfxDriverInfo(os, vendor, devices, feature, featureStatus, driverComparator, driverVersion, suggestedVersion)) 1.18 +#define APPEND_TO_DRIVER_BLOCKLIST2(os, vendor, devices, feature, featureStatus, driverComparator, driverVersion) \ 1.19 + mDriverInfo->AppendElement(GfxDriverInfo(os, vendor, devices, feature, featureStatus, driverComparator, driverVersion)) 1.20 + 1.21 +#define APPEND_TO_DRIVER_BLOCKLIST_RANGE(os, vendor, devices, feature, featureStatus, driverComparator, driverVersion, driverVersionMax, suggestedVersion) \ 1.22 + do { \ 1.23 + MOZ_ASSERT(driverComparator == DRIVER_BETWEEN_EXCLUSIVE || \ 1.24 + driverComparator == DRIVER_BETWEEN_INCLUSIVE || \ 1.25 + driverComparator == DRIVER_BETWEEN_INCLUSIVE_START); \ 1.26 + GfxDriverInfo info(os, vendor, devices, feature, featureStatus, driverComparator, driverVersion, suggestedVersion); \ 1.27 + info.mDriverVersionMax = driverVersionMax; \ 1.28 + mDriverInfo->AppendElement(info); \ 1.29 + } while (false) 1.30 + 1.31 +namespace mozilla { 1.32 +namespace widget { 1.33 + 1.34 +enum OperatingSystem { 1.35 + DRIVER_OS_UNKNOWN = 0, 1.36 + DRIVER_OS_WINDOWS_XP, 1.37 + DRIVER_OS_WINDOWS_SERVER_2003, 1.38 + DRIVER_OS_WINDOWS_VISTA, 1.39 + DRIVER_OS_WINDOWS_7, 1.40 + DRIVER_OS_WINDOWS_8, 1.41 + DRIVER_OS_WINDOWS_8_1, 1.42 + DRIVER_OS_LINUX, 1.43 + DRIVER_OS_OS_X_10_5, 1.44 + DRIVER_OS_OS_X_10_6, 1.45 + DRIVER_OS_OS_X_10_7, 1.46 + DRIVER_OS_OS_X_10_8, 1.47 + DRIVER_OS_ANDROID, 1.48 + DRIVER_OS_ALL 1.49 +}; 1.50 + 1.51 +enum VersionComparisonOp { 1.52 + DRIVER_LESS_THAN, // driver < version 1.53 + DRIVER_LESS_THAN_OR_EQUAL, // driver <= version 1.54 + DRIVER_GREATER_THAN, // driver > version 1.55 + DRIVER_GREATER_THAN_OR_EQUAL, // driver >= version 1.56 + DRIVER_EQUAL, // driver == version 1.57 + DRIVER_NOT_EQUAL, // driver != version 1.58 + DRIVER_BETWEEN_EXCLUSIVE, // driver > version && driver < versionMax 1.59 + DRIVER_BETWEEN_INCLUSIVE, // driver >= version && driver <= versionMax 1.60 + DRIVER_BETWEEN_INCLUSIVE_START, // driver >= version && driver < versionMax 1.61 + DRIVER_COMPARISON_IGNORED 1.62 +}; 1.63 + 1.64 +enum DeviceFamily { 1.65 + IntelGMA500, 1.66 + IntelGMA900, 1.67 + IntelGMA950, 1.68 + IntelGMA3150, 1.69 + IntelGMAX3000, 1.70 + IntelGMAX4500HD, 1.71 + IntelMobileHDGraphics, 1.72 + NvidiaBlockD3D9Layers, 1.73 + RadeonX1000, 1.74 + Geforce7300GT, 1.75 + DeviceFamilyMax 1.76 +}; 1.77 + 1.78 +enum DeviceVendor { 1.79 + VendorAll, 1.80 + VendorIntel, 1.81 + VendorNVIDIA, 1.82 + VendorAMD, 1.83 + VendorATI, 1.84 + VendorMicrosoft, 1.85 + DeviceVendorMax 1.86 +}; 1.87 + 1.88 +/* Array of devices to match, or an empty array for all devices */ 1.89 +typedef nsTArray<nsString> GfxDeviceFamily; 1.90 + 1.91 +struct GfxDriverInfo 1.92 +{ 1.93 + // If |ownDevices| is true, you are transferring ownership of the devices 1.94 + // array, and it will be deleted when this GfxDriverInfo is destroyed. 1.95 + GfxDriverInfo(OperatingSystem os, nsAString& vendor, GfxDeviceFamily* devices, 1.96 + int32_t feature, int32_t featureStatus, VersionComparisonOp op, 1.97 + uint64_t driverVersion, const char *suggestedVersion = nullptr, 1.98 + bool ownDevices = false); 1.99 + 1.100 + GfxDriverInfo(); 1.101 + GfxDriverInfo(const GfxDriverInfo&); 1.102 + ~GfxDriverInfo(); 1.103 + 1.104 + OperatingSystem mOperatingSystem; 1.105 + uint32_t mOperatingSystemVersion; 1.106 + 1.107 + nsString mAdapterVendor; 1.108 + 1.109 + static GfxDeviceFamily* const allDevices; 1.110 + GfxDeviceFamily* mDevices; 1.111 + 1.112 + // Whether the mDevices array should be deleted when this structure is 1.113 + // deallocated. False by default. 1.114 + bool mDeleteDevices; 1.115 + 1.116 + /* A feature from nsIGfxInfo, or all features */ 1.117 + int32_t mFeature; 1.118 + static int32_t allFeatures; 1.119 + 1.120 + /* A feature status from nsIGfxInfo */ 1.121 + int32_t mFeatureStatus; 1.122 + 1.123 + VersionComparisonOp mComparisonOp; 1.124 + 1.125 + /* versions are assumed to be A.B.C.D packed as 0xAAAABBBBCCCCDDDD */ 1.126 + uint64_t mDriverVersion; 1.127 + uint64_t mDriverVersionMax; 1.128 + static uint64_t allDriverVersions; 1.129 + 1.130 + const char *mSuggestedVersion; 1.131 + 1.132 + static const GfxDeviceFamily* GetDeviceFamily(DeviceFamily id); 1.133 + static GfxDeviceFamily* mDeviceFamilies[DeviceFamilyMax]; 1.134 + 1.135 + static const nsAString& GetDeviceVendor(DeviceVendor id); 1.136 + static nsAString* mDeviceVendors[DeviceVendorMax]; 1.137 + 1.138 + nsString mModel, mHardware, mProduct, mManufacturer; 1.139 +}; 1.140 + 1.141 +#define GFX_DRIVER_VERSION(a,b,c,d) \ 1.142 + ((uint64_t(a)<<48) | (uint64_t(b)<<32) | (uint64_t(c)<<16) | uint64_t(d)) 1.143 + 1.144 +inline uint64_t 1.145 +V(uint32_t a, uint32_t b, uint32_t c, uint32_t d) 1.146 +{ 1.147 + // We make sure every driver number is padded by 0s, this will allow us the 1.148 + // easiest 'compare as if decimals' approach. See ParseDriverVersion for a 1.149 + // more extensive explanation of this approach. 1.150 + while (b > 0 && b < 1000) { 1.151 + b *= 10; 1.152 + } 1.153 + while (c > 0 && c < 1000) { 1.154 + c *= 10; 1.155 + } 1.156 + while (d > 0 && d < 1000) { 1.157 + d *= 10; 1.158 + } 1.159 + return GFX_DRIVER_VERSION(a, b, c, d); 1.160 +} 1.161 + 1.162 +// All destination string storage needs to have at least 5 bytes available. 1.163 +inline bool SplitDriverVersion(const char *aSource, char *aAStr, char *aBStr, char *aCStr, char *aDStr) 1.164 +{ 1.165 + // sscanf doesn't do what we want here to we parse this manually. 1.166 + int len = strlen(aSource); 1.167 + char *dest[4] = { aAStr, aBStr, aCStr, aDStr }; 1.168 + unsigned destIdx = 0; 1.169 + unsigned destPos = 0; 1.170 + 1.171 + for (int i = 0; i < len; i++) { 1.172 + if (destIdx > ArrayLength(dest)) { 1.173 + // Invalid format found. Ensure we don't access dest beyond bounds. 1.174 + return false; 1.175 + } 1.176 + 1.177 + if (aSource[i] == '.') { 1.178 + dest[destIdx++][destPos] = 0; 1.179 + destPos = 0; 1.180 + continue; 1.181 + } 1.182 + 1.183 + if (destPos > 3) { 1.184 + // Ignore more than 4 chars. Ensure we never access dest[destIdx] 1.185 + // beyond its bounds. 1.186 + continue; 1.187 + } 1.188 + 1.189 + dest[destIdx][destPos++] = aSource[i]; 1.190 + } 1.191 + 1.192 + // Add last terminator. 1.193 + dest[destIdx][destPos] = 0; 1.194 + 1.195 + if (destIdx != ArrayLength(dest) - 1) { 1.196 + return false; 1.197 + } 1.198 + return true; 1.199 +} 1.200 + 1.201 +// This allows us to pad driver version 'substrings' with 0s, this 1.202 +// effectively allows us to treat the version numbers as 'decimals'. This is 1.203 +// a little strange but this method seems to do the right thing for all 1.204 +// different vendor's driver strings. i.e. .98 will become 9800, which is 1.205 +// larger than .978 which would become 9780. 1.206 +inline void PadDriverDecimal(char *aString) 1.207 +{ 1.208 + for (int i = 0; i < 4; i++) { 1.209 + if (!aString[i]) { 1.210 + for (int c = i; c < 4; c++) { 1.211 + aString[c] = '0'; 1.212 + } 1.213 + break; 1.214 + } 1.215 + } 1.216 + aString[4] = 0; 1.217 +} 1.218 + 1.219 +inline bool 1.220 +ParseDriverVersion(const nsAString& aVersion, uint64_t *aNumericVersion) 1.221 +{ 1.222 + *aNumericVersion = 0; 1.223 + 1.224 +#if defined(XP_WIN) 1.225 + int a, b, c, d; 1.226 + char aStr[8], bStr[8], cStr[8], dStr[8]; 1.227 + /* honestly, why do I even bother */ 1.228 + if (!SplitDriverVersion(NS_LossyConvertUTF16toASCII(aVersion).get(), aStr, bStr, cStr, dStr)) 1.229 + return false; 1.230 + 1.231 + PadDriverDecimal(bStr); 1.232 + PadDriverDecimal(cStr); 1.233 + PadDriverDecimal(dStr); 1.234 + 1.235 + a = atoi(aStr); 1.236 + b = atoi(bStr); 1.237 + c = atoi(cStr); 1.238 + d = atoi(dStr); 1.239 + 1.240 + if (a < 0 || a > 0xffff) return false; 1.241 + if (b < 0 || b > 0xffff) return false; 1.242 + if (c < 0 || c > 0xffff) return false; 1.243 + if (d < 0 || d > 0xffff) return false; 1.244 + 1.245 + *aNumericVersion = GFX_DRIVER_VERSION(a, b, c, d); 1.246 + return true; 1.247 +#elif defined(ANDROID) 1.248 + // Can't use aVersion.ToInteger() because that's not compiled into our code 1.249 + // unless we have XPCOM_GLUE_AVOID_NSPR disabled. 1.250 + *aNumericVersion = atoi(NS_LossyConvertUTF16toASCII(aVersion).get()); 1.251 + return true; 1.252 +#else 1.253 + return false; 1.254 +#endif 1.255 +} 1.256 + 1.257 +} 1.258 +} 1.259 + 1.260 +#endif /*__mozilla_widget_GfxDriverInfo_h__ */