1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/widget/cocoa/GfxInfo.mm Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,369 @@ 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 +#include <OpenGL/OpenGL.h> 1.10 +#include <OpenGL/CGLRenderers.h> 1.11 + 1.12 +#include "mozilla/ArrayUtils.h" 1.13 + 1.14 +#include "GfxInfo.h" 1.15 +#include "nsUnicharUtils.h" 1.16 +#include "nsCocoaFeatures.h" 1.17 +#include "mozilla/Preferences.h" 1.18 +#include <algorithm> 1.19 + 1.20 +#import <Foundation/Foundation.h> 1.21 +#import <IOKit/IOKitLib.h> 1.22 +#import <Cocoa/Cocoa.h> 1.23 + 1.24 +#if defined(MOZ_CRASHREPORTER) 1.25 +#include "nsExceptionHandler.h" 1.26 +#include "nsICrashReporter.h" 1.27 +#define NS_CRASHREPORTER_CONTRACTID "@mozilla.org/toolkit/crash-reporter;1" 1.28 +#endif 1.29 + 1.30 +#define MAC_OS_X_VERSION_MASK 0x0000FFFF 1.31 +#define MAC_OS_X_VERSION_MAJOR_MASK 0x0000FFF0 1.32 +#define MAC_OS_X_VERSION_10_6_HEX 0x00001060 1.33 +#define MAC_OS_X_VERSION_10_7_HEX 0x00001070 1.34 +#define MAC_OS_X_VERSION_10_8_HEX 0x00001080 1.35 + 1.36 +using namespace mozilla; 1.37 +using namespace mozilla::widget; 1.38 + 1.39 +#ifdef DEBUG 1.40 +NS_IMPL_ISUPPORTS_INHERITED(GfxInfo, GfxInfoBase, nsIGfxInfoDebug) 1.41 +#endif 1.42 + 1.43 +GfxInfo::GfxInfo() 1.44 +{ 1.45 +} 1.46 + 1.47 +static OperatingSystem 1.48 +OSXVersionToOperatingSystem(uint32_t aOSXVersion) 1.49 +{ 1.50 + switch (aOSXVersion & MAC_OS_X_VERSION_MAJOR_MASK) { 1.51 + case MAC_OS_X_VERSION_10_6_HEX: 1.52 + return DRIVER_OS_OS_X_10_6; 1.53 + case MAC_OS_X_VERSION_10_7_HEX: 1.54 + return DRIVER_OS_OS_X_10_7; 1.55 + case MAC_OS_X_VERSION_10_8_HEX: 1.56 + return DRIVER_OS_OS_X_10_8; 1.57 + } 1.58 + 1.59 + return DRIVER_OS_UNKNOWN; 1.60 +} 1.61 +// The following three functions are derived from Chromium code 1.62 +static CFTypeRef SearchPortForProperty(io_registry_entry_t dspPort, 1.63 + CFStringRef propertyName) 1.64 +{ 1.65 + return IORegistryEntrySearchCFProperty(dspPort, 1.66 + kIOServicePlane, 1.67 + propertyName, 1.68 + kCFAllocatorDefault, 1.69 + kIORegistryIterateRecursively | 1.70 + kIORegistryIterateParents); 1.71 +} 1.72 + 1.73 +static uint32_t IntValueOfCFData(CFDataRef d) 1.74 +{ 1.75 + uint32_t value = 0; 1.76 + 1.77 + if (d) { 1.78 + const uint32_t *vp = reinterpret_cast<const uint32_t*>(CFDataGetBytePtr(d)); 1.79 + if (vp != NULL) 1.80 + value = *vp; 1.81 + } 1.82 + 1.83 + return value; 1.84 +} 1.85 + 1.86 +void 1.87 +GfxInfo::GetDeviceInfo() 1.88 +{ 1.89 + io_registry_entry_t dsp_port = CGDisplayIOServicePort(kCGDirectMainDisplay); 1.90 + CFTypeRef vendor_id_ref = SearchPortForProperty(dsp_port, CFSTR("vendor-id")); 1.91 + if (vendor_id_ref) { 1.92 + mAdapterVendorID.AppendPrintf("0x%4x", IntValueOfCFData((CFDataRef)vendor_id_ref)); 1.93 + CFRelease(vendor_id_ref); 1.94 + } 1.95 + CFTypeRef device_id_ref = SearchPortForProperty(dsp_port, CFSTR("device-id")); 1.96 + if (device_id_ref) { 1.97 + mAdapterDeviceID.AppendPrintf("0x%4x", IntValueOfCFData((CFDataRef)device_id_ref)); 1.98 + CFRelease(device_id_ref); 1.99 + } 1.100 +} 1.101 + 1.102 +nsresult 1.103 +GfxInfo::Init() 1.104 +{ 1.105 + nsresult rv = GfxInfoBase::Init(); 1.106 + 1.107 + // Calling CGLQueryRendererInfo causes us to switch to the discrete GPU 1.108 + // even when we don't want to. We'll avoid doing so for now and just 1.109 + // use the device ids. 1.110 + 1.111 + GetDeviceInfo(); 1.112 + 1.113 + AddCrashReportAnnotations(); 1.114 + 1.115 + mOSXVersion = nsCocoaFeatures::OSXVersion(); 1.116 + 1.117 + return rv; 1.118 +} 1.119 + 1.120 +NS_IMETHODIMP 1.121 +GfxInfo::GetD2DEnabled(bool *aEnabled) 1.122 +{ 1.123 + return NS_ERROR_FAILURE; 1.124 +} 1.125 + 1.126 +NS_IMETHODIMP 1.127 +GfxInfo::GetDWriteEnabled(bool *aEnabled) 1.128 +{ 1.129 + return NS_ERROR_FAILURE; 1.130 +} 1.131 + 1.132 +/* readonly attribute DOMString DWriteVersion; */ 1.133 +NS_IMETHODIMP 1.134 +GfxInfo::GetDWriteVersion(nsAString & aDwriteVersion) 1.135 +{ 1.136 + return NS_ERROR_FAILURE; 1.137 +} 1.138 + 1.139 +/* readonly attribute DOMString cleartypeParameters; */ 1.140 +NS_IMETHODIMP 1.141 +GfxInfo::GetCleartypeParameters(nsAString & aCleartypeParams) 1.142 +{ 1.143 + return NS_ERROR_FAILURE; 1.144 +} 1.145 + 1.146 +/* readonly attribute DOMString adapterDescription; */ 1.147 +NS_IMETHODIMP 1.148 +GfxInfo::GetAdapterDescription(nsAString & aAdapterDescription) 1.149 +{ 1.150 + aAdapterDescription.AssignLiteral(""); 1.151 + return NS_OK; 1.152 +} 1.153 + 1.154 +/* readonly attribute DOMString adapterDescription2; */ 1.155 +NS_IMETHODIMP 1.156 +GfxInfo::GetAdapterDescription2(nsAString & aAdapterDescription) 1.157 +{ 1.158 + return NS_ERROR_FAILURE; 1.159 +} 1.160 + 1.161 +/* readonly attribute DOMString adapterRAM; */ 1.162 +NS_IMETHODIMP 1.163 +GfxInfo::GetAdapterRAM(nsAString & aAdapterRAM) 1.164 +{ 1.165 + aAdapterRAM = mAdapterRAMString; 1.166 + return NS_OK; 1.167 +} 1.168 + 1.169 +/* readonly attribute DOMString adapterRAM2; */ 1.170 +NS_IMETHODIMP 1.171 +GfxInfo::GetAdapterRAM2(nsAString & aAdapterRAM) 1.172 +{ 1.173 + return NS_ERROR_FAILURE; 1.174 +} 1.175 + 1.176 +/* readonly attribute DOMString adapterDriver; */ 1.177 +NS_IMETHODIMP 1.178 +GfxInfo::GetAdapterDriver(nsAString & aAdapterDriver) 1.179 +{ 1.180 + aAdapterDriver.AssignLiteral(""); 1.181 + return NS_OK; 1.182 +} 1.183 + 1.184 +/* readonly attribute DOMString adapterDriver2; */ 1.185 +NS_IMETHODIMP 1.186 +GfxInfo::GetAdapterDriver2(nsAString & aAdapterDriver) 1.187 +{ 1.188 + return NS_ERROR_FAILURE; 1.189 +} 1.190 + 1.191 +/* readonly attribute DOMString adapterDriverVersion; */ 1.192 +NS_IMETHODIMP 1.193 +GfxInfo::GetAdapterDriverVersion(nsAString & aAdapterDriverVersion) 1.194 +{ 1.195 + aAdapterDriverVersion.AssignLiteral(""); 1.196 + return NS_OK; 1.197 +} 1.198 + 1.199 +/* readonly attribute DOMString adapterDriverVersion2; */ 1.200 +NS_IMETHODIMP 1.201 +GfxInfo::GetAdapterDriverVersion2(nsAString & aAdapterDriverVersion) 1.202 +{ 1.203 + return NS_ERROR_FAILURE; 1.204 +} 1.205 + 1.206 +/* readonly attribute DOMString adapterDriverDate; */ 1.207 +NS_IMETHODIMP 1.208 +GfxInfo::GetAdapterDriverDate(nsAString & aAdapterDriverDate) 1.209 +{ 1.210 + aAdapterDriverDate.AssignLiteral(""); 1.211 + return NS_OK; 1.212 +} 1.213 + 1.214 +/* readonly attribute DOMString adapterDriverDate2; */ 1.215 +NS_IMETHODIMP 1.216 +GfxInfo::GetAdapterDriverDate2(nsAString & aAdapterDriverDate) 1.217 +{ 1.218 + return NS_ERROR_FAILURE; 1.219 +} 1.220 + 1.221 +/* readonly attribute DOMString adapterVendorID; */ 1.222 +NS_IMETHODIMP 1.223 +GfxInfo::GetAdapterVendorID(nsAString & aAdapterVendorID) 1.224 +{ 1.225 + aAdapterVendorID = mAdapterVendorID; 1.226 + return NS_OK; 1.227 +} 1.228 + 1.229 +/* readonly attribute DOMString adapterVendorID2; */ 1.230 +NS_IMETHODIMP 1.231 +GfxInfo::GetAdapterVendorID2(nsAString & aAdapterVendorID) 1.232 +{ 1.233 + return NS_ERROR_FAILURE; 1.234 +} 1.235 + 1.236 +/* readonly attribute DOMString adapterDeviceID; */ 1.237 +NS_IMETHODIMP 1.238 +GfxInfo::GetAdapterDeviceID(nsAString & aAdapterDeviceID) 1.239 +{ 1.240 + aAdapterDeviceID = mAdapterDeviceID; 1.241 + return NS_OK; 1.242 +} 1.243 + 1.244 +/* readonly attribute DOMString adapterDeviceID2; */ 1.245 +NS_IMETHODIMP 1.246 +GfxInfo::GetAdapterDeviceID2(nsAString & aAdapterDeviceID) 1.247 +{ 1.248 + return NS_ERROR_FAILURE; 1.249 +} 1.250 + 1.251 +/* readonly attribute boolean isGPU2Active; */ 1.252 +NS_IMETHODIMP 1.253 +GfxInfo::GetIsGPU2Active(bool* aIsGPU2Active) 1.254 +{ 1.255 + return NS_ERROR_FAILURE; 1.256 +} 1.257 + 1.258 +void 1.259 +GfxInfo::AddCrashReportAnnotations() 1.260 +{ 1.261 +#if defined(MOZ_CRASHREPORTER) 1.262 + nsString deviceID, vendorID; 1.263 + nsAutoCString narrowDeviceID, narrowVendorID; 1.264 + 1.265 + GetAdapterDeviceID(deviceID); 1.266 + CopyUTF16toUTF8(deviceID, narrowDeviceID); 1.267 + GetAdapterVendorID(vendorID); 1.268 + CopyUTF16toUTF8(vendorID, narrowVendorID); 1.269 + 1.270 + CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("AdapterVendorID"), 1.271 + narrowVendorID); 1.272 + CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("AdapterDeviceID"), 1.273 + narrowDeviceID); 1.274 + /* Add an App Note for now so that we get the data immediately. These 1.275 + * can go away after we store the above in the socorro db */ 1.276 + nsAutoCString note; 1.277 + /* AppendPrintf only supports 32 character strings, mrghh. */ 1.278 + note.Append("AdapterVendorID: "); 1.279 + note.Append(narrowVendorID); 1.280 + note.Append(", AdapterDeviceID: "); 1.281 + note.Append(narrowDeviceID); 1.282 + CrashReporter::AppendAppNotesToCrashReport(note); 1.283 +#endif 1.284 +} 1.285 + 1.286 +// We don't support checking driver versions on Mac. 1.287 +#define IMPLEMENT_MAC_DRIVER_BLOCKLIST(os, vendor, device, features, blockOn) \ 1.288 + APPEND_TO_DRIVER_BLOCKLIST(os, vendor, device, features, blockOn, \ 1.289 + DRIVER_COMPARISON_IGNORED, V(0,0,0,0), "") 1.290 + 1.291 + 1.292 +const nsTArray<GfxDriverInfo>& 1.293 +GfxInfo::GetGfxDriverInfo() 1.294 +{ 1.295 + if (!mDriverInfo->Length()) { 1.296 + IMPLEMENT_MAC_DRIVER_BLOCKLIST(DRIVER_OS_ALL, 1.297 + (nsAString&) GfxDriverInfo::GetDeviceVendor(VendorATI), GfxDriverInfo::allDevices, 1.298 + nsIGfxInfo::FEATURE_WEBGL_MSAA, nsIGfxInfo::FEATURE_BLOCKED_OS_VERSION); 1.299 + IMPLEMENT_MAC_DRIVER_BLOCKLIST(DRIVER_OS_ALL, 1.300 + (nsAString&) GfxDriverInfo::GetDeviceVendor(VendorATI), (GfxDeviceFamily*) GfxDriverInfo::GetDeviceFamily(RadeonX1000), 1.301 + nsIGfxInfo::FEATURE_OPENGL_LAYERS, nsIGfxInfo::FEATURE_BLOCKED_DEVICE); 1.302 + IMPLEMENT_MAC_DRIVER_BLOCKLIST(DRIVER_OS_ALL, 1.303 + (nsAString&) GfxDriverInfo::GetDeviceVendor(VendorNVIDIA), (GfxDeviceFamily*) GfxDriverInfo::GetDeviceFamily(Geforce7300GT), 1.304 + nsIGfxInfo::FEATURE_WEBGL_OPENGL, nsIGfxInfo::FEATURE_BLOCKED_DEVICE); 1.305 + } 1.306 + return *mDriverInfo; 1.307 +} 1.308 + 1.309 +nsresult 1.310 +GfxInfo::GetFeatureStatusImpl(int32_t aFeature, 1.311 + int32_t* aStatus, 1.312 + nsAString& aSuggestedDriverVersion, 1.313 + const nsTArray<GfxDriverInfo>& aDriverInfo, 1.314 + OperatingSystem* aOS /* = nullptr */) 1.315 +{ 1.316 + NS_ENSURE_ARG_POINTER(aStatus); 1.317 + aSuggestedDriverVersion.SetIsVoid(true); 1.318 + *aStatus = nsIGfxInfo::FEATURE_STATUS_UNKNOWN; 1.319 + OperatingSystem os = OSXVersionToOperatingSystem(mOSXVersion); 1.320 + if (aOS) 1.321 + *aOS = os; 1.322 + 1.323 + // Don't evaluate special cases when we're evaluating the downloaded blocklist. 1.324 + if (!aDriverInfo.Length()) { 1.325 + if (aFeature == nsIGfxInfo::FEATURE_WEBGL_MSAA) { 1.326 + // Blacklist all ATI cards on OSX, except for 1.327 + // 0x6760 and 0x9488 1.328 + if (mAdapterVendorID.Equals(GfxDriverInfo::GetDeviceVendor(VendorATI), nsCaseInsensitiveStringComparator()) && 1.329 + (mAdapterDeviceID.LowerCaseEqualsLiteral("0x6760") || 1.330 + mAdapterDeviceID.LowerCaseEqualsLiteral("0x9488"))) { 1.331 + *aStatus = nsIGfxInfo::FEATURE_NO_INFO; 1.332 + return NS_OK; 1.333 + } 1.334 + } 1.335 + } 1.336 + 1.337 + return GfxInfoBase::GetFeatureStatusImpl(aFeature, aStatus, aSuggestedDriverVersion, aDriverInfo, &os); 1.338 +} 1.339 + 1.340 +#ifdef DEBUG 1.341 + 1.342 +// Implement nsIGfxInfoDebug 1.343 + 1.344 +/* void spoofVendorID (in DOMString aVendorID); */ 1.345 +NS_IMETHODIMP GfxInfo::SpoofVendorID(const nsAString & aVendorID) 1.346 +{ 1.347 + mAdapterVendorID = aVendorID; 1.348 + return NS_OK; 1.349 +} 1.350 + 1.351 +/* void spoofDeviceID (in unsigned long aDeviceID); */ 1.352 +NS_IMETHODIMP GfxInfo::SpoofDeviceID(const nsAString & aDeviceID) 1.353 +{ 1.354 + mAdapterDeviceID = aDeviceID; 1.355 + return NS_OK; 1.356 +} 1.357 + 1.358 +/* void spoofDriverVersion (in DOMString aDriverVersion); */ 1.359 +NS_IMETHODIMP GfxInfo::SpoofDriverVersion(const nsAString & aDriverVersion) 1.360 +{ 1.361 + mDriverVersion = aDriverVersion; 1.362 + return NS_OK; 1.363 +} 1.364 + 1.365 +/* void spoofOSVersion (in unsigned long aVersion); */ 1.366 +NS_IMETHODIMP GfxInfo::SpoofOSVersion(uint32_t aVersion) 1.367 +{ 1.368 + mOSXVersion = aVersion; 1.369 + return NS_OK; 1.370 +} 1.371 + 1.372 +#endif