widget/cocoa/GfxInfo.mm

Wed, 31 Dec 2014 06:55:50 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:55:50 +0100
changeset 2
7e26c7da4463
permissions
-rw-r--r--

Added tag UPSTREAM_283F7C6 for changeset ca08bd8f51b2

michael@0 1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
michael@0 2 /* This Source Code Form is subject to the terms of the Mozilla Public
michael@0 3 * License, v. 2.0. If a copy of the MPL was not distributed with this
michael@0 4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
michael@0 5
michael@0 6 #include <OpenGL/OpenGL.h>
michael@0 7 #include <OpenGL/CGLRenderers.h>
michael@0 8
michael@0 9 #include "mozilla/ArrayUtils.h"
michael@0 10
michael@0 11 #include "GfxInfo.h"
michael@0 12 #include "nsUnicharUtils.h"
michael@0 13 #include "nsCocoaFeatures.h"
michael@0 14 #include "mozilla/Preferences.h"
michael@0 15 #include <algorithm>
michael@0 16
michael@0 17 #import <Foundation/Foundation.h>
michael@0 18 #import <IOKit/IOKitLib.h>
michael@0 19 #import <Cocoa/Cocoa.h>
michael@0 20
michael@0 21 #if defined(MOZ_CRASHREPORTER)
michael@0 22 #include "nsExceptionHandler.h"
michael@0 23 #include "nsICrashReporter.h"
michael@0 24 #define NS_CRASHREPORTER_CONTRACTID "@mozilla.org/toolkit/crash-reporter;1"
michael@0 25 #endif
michael@0 26
michael@0 27 #define MAC_OS_X_VERSION_MASK 0x0000FFFF
michael@0 28 #define MAC_OS_X_VERSION_MAJOR_MASK 0x0000FFF0
michael@0 29 #define MAC_OS_X_VERSION_10_6_HEX 0x00001060
michael@0 30 #define MAC_OS_X_VERSION_10_7_HEX 0x00001070
michael@0 31 #define MAC_OS_X_VERSION_10_8_HEX 0x00001080
michael@0 32
michael@0 33 using namespace mozilla;
michael@0 34 using namespace mozilla::widget;
michael@0 35
michael@0 36 #ifdef DEBUG
michael@0 37 NS_IMPL_ISUPPORTS_INHERITED(GfxInfo, GfxInfoBase, nsIGfxInfoDebug)
michael@0 38 #endif
michael@0 39
michael@0 40 GfxInfo::GfxInfo()
michael@0 41 {
michael@0 42 }
michael@0 43
michael@0 44 static OperatingSystem
michael@0 45 OSXVersionToOperatingSystem(uint32_t aOSXVersion)
michael@0 46 {
michael@0 47 switch (aOSXVersion & MAC_OS_X_VERSION_MAJOR_MASK) {
michael@0 48 case MAC_OS_X_VERSION_10_6_HEX:
michael@0 49 return DRIVER_OS_OS_X_10_6;
michael@0 50 case MAC_OS_X_VERSION_10_7_HEX:
michael@0 51 return DRIVER_OS_OS_X_10_7;
michael@0 52 case MAC_OS_X_VERSION_10_8_HEX:
michael@0 53 return DRIVER_OS_OS_X_10_8;
michael@0 54 }
michael@0 55
michael@0 56 return DRIVER_OS_UNKNOWN;
michael@0 57 }
michael@0 58 // The following three functions are derived from Chromium code
michael@0 59 static CFTypeRef SearchPortForProperty(io_registry_entry_t dspPort,
michael@0 60 CFStringRef propertyName)
michael@0 61 {
michael@0 62 return IORegistryEntrySearchCFProperty(dspPort,
michael@0 63 kIOServicePlane,
michael@0 64 propertyName,
michael@0 65 kCFAllocatorDefault,
michael@0 66 kIORegistryIterateRecursively |
michael@0 67 kIORegistryIterateParents);
michael@0 68 }
michael@0 69
michael@0 70 static uint32_t IntValueOfCFData(CFDataRef d)
michael@0 71 {
michael@0 72 uint32_t value = 0;
michael@0 73
michael@0 74 if (d) {
michael@0 75 const uint32_t *vp = reinterpret_cast<const uint32_t*>(CFDataGetBytePtr(d));
michael@0 76 if (vp != NULL)
michael@0 77 value = *vp;
michael@0 78 }
michael@0 79
michael@0 80 return value;
michael@0 81 }
michael@0 82
michael@0 83 void
michael@0 84 GfxInfo::GetDeviceInfo()
michael@0 85 {
michael@0 86 io_registry_entry_t dsp_port = CGDisplayIOServicePort(kCGDirectMainDisplay);
michael@0 87 CFTypeRef vendor_id_ref = SearchPortForProperty(dsp_port, CFSTR("vendor-id"));
michael@0 88 if (vendor_id_ref) {
michael@0 89 mAdapterVendorID.AppendPrintf("0x%4x", IntValueOfCFData((CFDataRef)vendor_id_ref));
michael@0 90 CFRelease(vendor_id_ref);
michael@0 91 }
michael@0 92 CFTypeRef device_id_ref = SearchPortForProperty(dsp_port, CFSTR("device-id"));
michael@0 93 if (device_id_ref) {
michael@0 94 mAdapterDeviceID.AppendPrintf("0x%4x", IntValueOfCFData((CFDataRef)device_id_ref));
michael@0 95 CFRelease(device_id_ref);
michael@0 96 }
michael@0 97 }
michael@0 98
michael@0 99 nsresult
michael@0 100 GfxInfo::Init()
michael@0 101 {
michael@0 102 nsresult rv = GfxInfoBase::Init();
michael@0 103
michael@0 104 // Calling CGLQueryRendererInfo causes us to switch to the discrete GPU
michael@0 105 // even when we don't want to. We'll avoid doing so for now and just
michael@0 106 // use the device ids.
michael@0 107
michael@0 108 GetDeviceInfo();
michael@0 109
michael@0 110 AddCrashReportAnnotations();
michael@0 111
michael@0 112 mOSXVersion = nsCocoaFeatures::OSXVersion();
michael@0 113
michael@0 114 return rv;
michael@0 115 }
michael@0 116
michael@0 117 NS_IMETHODIMP
michael@0 118 GfxInfo::GetD2DEnabled(bool *aEnabled)
michael@0 119 {
michael@0 120 return NS_ERROR_FAILURE;
michael@0 121 }
michael@0 122
michael@0 123 NS_IMETHODIMP
michael@0 124 GfxInfo::GetDWriteEnabled(bool *aEnabled)
michael@0 125 {
michael@0 126 return NS_ERROR_FAILURE;
michael@0 127 }
michael@0 128
michael@0 129 /* readonly attribute DOMString DWriteVersion; */
michael@0 130 NS_IMETHODIMP
michael@0 131 GfxInfo::GetDWriteVersion(nsAString & aDwriteVersion)
michael@0 132 {
michael@0 133 return NS_ERROR_FAILURE;
michael@0 134 }
michael@0 135
michael@0 136 /* readonly attribute DOMString cleartypeParameters; */
michael@0 137 NS_IMETHODIMP
michael@0 138 GfxInfo::GetCleartypeParameters(nsAString & aCleartypeParams)
michael@0 139 {
michael@0 140 return NS_ERROR_FAILURE;
michael@0 141 }
michael@0 142
michael@0 143 /* readonly attribute DOMString adapterDescription; */
michael@0 144 NS_IMETHODIMP
michael@0 145 GfxInfo::GetAdapterDescription(nsAString & aAdapterDescription)
michael@0 146 {
michael@0 147 aAdapterDescription.AssignLiteral("");
michael@0 148 return NS_OK;
michael@0 149 }
michael@0 150
michael@0 151 /* readonly attribute DOMString adapterDescription2; */
michael@0 152 NS_IMETHODIMP
michael@0 153 GfxInfo::GetAdapterDescription2(nsAString & aAdapterDescription)
michael@0 154 {
michael@0 155 return NS_ERROR_FAILURE;
michael@0 156 }
michael@0 157
michael@0 158 /* readonly attribute DOMString adapterRAM; */
michael@0 159 NS_IMETHODIMP
michael@0 160 GfxInfo::GetAdapterRAM(nsAString & aAdapterRAM)
michael@0 161 {
michael@0 162 aAdapterRAM = mAdapterRAMString;
michael@0 163 return NS_OK;
michael@0 164 }
michael@0 165
michael@0 166 /* readonly attribute DOMString adapterRAM2; */
michael@0 167 NS_IMETHODIMP
michael@0 168 GfxInfo::GetAdapterRAM2(nsAString & aAdapterRAM)
michael@0 169 {
michael@0 170 return NS_ERROR_FAILURE;
michael@0 171 }
michael@0 172
michael@0 173 /* readonly attribute DOMString adapterDriver; */
michael@0 174 NS_IMETHODIMP
michael@0 175 GfxInfo::GetAdapterDriver(nsAString & aAdapterDriver)
michael@0 176 {
michael@0 177 aAdapterDriver.AssignLiteral("");
michael@0 178 return NS_OK;
michael@0 179 }
michael@0 180
michael@0 181 /* readonly attribute DOMString adapterDriver2; */
michael@0 182 NS_IMETHODIMP
michael@0 183 GfxInfo::GetAdapterDriver2(nsAString & aAdapterDriver)
michael@0 184 {
michael@0 185 return NS_ERROR_FAILURE;
michael@0 186 }
michael@0 187
michael@0 188 /* readonly attribute DOMString adapterDriverVersion; */
michael@0 189 NS_IMETHODIMP
michael@0 190 GfxInfo::GetAdapterDriverVersion(nsAString & aAdapterDriverVersion)
michael@0 191 {
michael@0 192 aAdapterDriverVersion.AssignLiteral("");
michael@0 193 return NS_OK;
michael@0 194 }
michael@0 195
michael@0 196 /* readonly attribute DOMString adapterDriverVersion2; */
michael@0 197 NS_IMETHODIMP
michael@0 198 GfxInfo::GetAdapterDriverVersion2(nsAString & aAdapterDriverVersion)
michael@0 199 {
michael@0 200 return NS_ERROR_FAILURE;
michael@0 201 }
michael@0 202
michael@0 203 /* readonly attribute DOMString adapterDriverDate; */
michael@0 204 NS_IMETHODIMP
michael@0 205 GfxInfo::GetAdapterDriverDate(nsAString & aAdapterDriverDate)
michael@0 206 {
michael@0 207 aAdapterDriverDate.AssignLiteral("");
michael@0 208 return NS_OK;
michael@0 209 }
michael@0 210
michael@0 211 /* readonly attribute DOMString adapterDriverDate2; */
michael@0 212 NS_IMETHODIMP
michael@0 213 GfxInfo::GetAdapterDriverDate2(nsAString & aAdapterDriverDate)
michael@0 214 {
michael@0 215 return NS_ERROR_FAILURE;
michael@0 216 }
michael@0 217
michael@0 218 /* readonly attribute DOMString adapterVendorID; */
michael@0 219 NS_IMETHODIMP
michael@0 220 GfxInfo::GetAdapterVendorID(nsAString & aAdapterVendorID)
michael@0 221 {
michael@0 222 aAdapterVendorID = mAdapterVendorID;
michael@0 223 return NS_OK;
michael@0 224 }
michael@0 225
michael@0 226 /* readonly attribute DOMString adapterVendorID2; */
michael@0 227 NS_IMETHODIMP
michael@0 228 GfxInfo::GetAdapterVendorID2(nsAString & aAdapterVendorID)
michael@0 229 {
michael@0 230 return NS_ERROR_FAILURE;
michael@0 231 }
michael@0 232
michael@0 233 /* readonly attribute DOMString adapterDeviceID; */
michael@0 234 NS_IMETHODIMP
michael@0 235 GfxInfo::GetAdapterDeviceID(nsAString & aAdapterDeviceID)
michael@0 236 {
michael@0 237 aAdapterDeviceID = mAdapterDeviceID;
michael@0 238 return NS_OK;
michael@0 239 }
michael@0 240
michael@0 241 /* readonly attribute DOMString adapterDeviceID2; */
michael@0 242 NS_IMETHODIMP
michael@0 243 GfxInfo::GetAdapterDeviceID2(nsAString & aAdapterDeviceID)
michael@0 244 {
michael@0 245 return NS_ERROR_FAILURE;
michael@0 246 }
michael@0 247
michael@0 248 /* readonly attribute boolean isGPU2Active; */
michael@0 249 NS_IMETHODIMP
michael@0 250 GfxInfo::GetIsGPU2Active(bool* aIsGPU2Active)
michael@0 251 {
michael@0 252 return NS_ERROR_FAILURE;
michael@0 253 }
michael@0 254
michael@0 255 void
michael@0 256 GfxInfo::AddCrashReportAnnotations()
michael@0 257 {
michael@0 258 #if defined(MOZ_CRASHREPORTER)
michael@0 259 nsString deviceID, vendorID;
michael@0 260 nsAutoCString narrowDeviceID, narrowVendorID;
michael@0 261
michael@0 262 GetAdapterDeviceID(deviceID);
michael@0 263 CopyUTF16toUTF8(deviceID, narrowDeviceID);
michael@0 264 GetAdapterVendorID(vendorID);
michael@0 265 CopyUTF16toUTF8(vendorID, narrowVendorID);
michael@0 266
michael@0 267 CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("AdapterVendorID"),
michael@0 268 narrowVendorID);
michael@0 269 CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("AdapterDeviceID"),
michael@0 270 narrowDeviceID);
michael@0 271 /* Add an App Note for now so that we get the data immediately. These
michael@0 272 * can go away after we store the above in the socorro db */
michael@0 273 nsAutoCString note;
michael@0 274 /* AppendPrintf only supports 32 character strings, mrghh. */
michael@0 275 note.Append("AdapterVendorID: ");
michael@0 276 note.Append(narrowVendorID);
michael@0 277 note.Append(", AdapterDeviceID: ");
michael@0 278 note.Append(narrowDeviceID);
michael@0 279 CrashReporter::AppendAppNotesToCrashReport(note);
michael@0 280 #endif
michael@0 281 }
michael@0 282
michael@0 283 // We don't support checking driver versions on Mac.
michael@0 284 #define IMPLEMENT_MAC_DRIVER_BLOCKLIST(os, vendor, device, features, blockOn) \
michael@0 285 APPEND_TO_DRIVER_BLOCKLIST(os, vendor, device, features, blockOn, \
michael@0 286 DRIVER_COMPARISON_IGNORED, V(0,0,0,0), "")
michael@0 287
michael@0 288
michael@0 289 const nsTArray<GfxDriverInfo>&
michael@0 290 GfxInfo::GetGfxDriverInfo()
michael@0 291 {
michael@0 292 if (!mDriverInfo->Length()) {
michael@0 293 IMPLEMENT_MAC_DRIVER_BLOCKLIST(DRIVER_OS_ALL,
michael@0 294 (nsAString&) GfxDriverInfo::GetDeviceVendor(VendorATI), GfxDriverInfo::allDevices,
michael@0 295 nsIGfxInfo::FEATURE_WEBGL_MSAA, nsIGfxInfo::FEATURE_BLOCKED_OS_VERSION);
michael@0 296 IMPLEMENT_MAC_DRIVER_BLOCKLIST(DRIVER_OS_ALL,
michael@0 297 (nsAString&) GfxDriverInfo::GetDeviceVendor(VendorATI), (GfxDeviceFamily*) GfxDriverInfo::GetDeviceFamily(RadeonX1000),
michael@0 298 nsIGfxInfo::FEATURE_OPENGL_LAYERS, nsIGfxInfo::FEATURE_BLOCKED_DEVICE);
michael@0 299 IMPLEMENT_MAC_DRIVER_BLOCKLIST(DRIVER_OS_ALL,
michael@0 300 (nsAString&) GfxDriverInfo::GetDeviceVendor(VendorNVIDIA), (GfxDeviceFamily*) GfxDriverInfo::GetDeviceFamily(Geforce7300GT),
michael@0 301 nsIGfxInfo::FEATURE_WEBGL_OPENGL, nsIGfxInfo::FEATURE_BLOCKED_DEVICE);
michael@0 302 }
michael@0 303 return *mDriverInfo;
michael@0 304 }
michael@0 305
michael@0 306 nsresult
michael@0 307 GfxInfo::GetFeatureStatusImpl(int32_t aFeature,
michael@0 308 int32_t* aStatus,
michael@0 309 nsAString& aSuggestedDriverVersion,
michael@0 310 const nsTArray<GfxDriverInfo>& aDriverInfo,
michael@0 311 OperatingSystem* aOS /* = nullptr */)
michael@0 312 {
michael@0 313 NS_ENSURE_ARG_POINTER(aStatus);
michael@0 314 aSuggestedDriverVersion.SetIsVoid(true);
michael@0 315 *aStatus = nsIGfxInfo::FEATURE_STATUS_UNKNOWN;
michael@0 316 OperatingSystem os = OSXVersionToOperatingSystem(mOSXVersion);
michael@0 317 if (aOS)
michael@0 318 *aOS = os;
michael@0 319
michael@0 320 // Don't evaluate special cases when we're evaluating the downloaded blocklist.
michael@0 321 if (!aDriverInfo.Length()) {
michael@0 322 if (aFeature == nsIGfxInfo::FEATURE_WEBGL_MSAA) {
michael@0 323 // Blacklist all ATI cards on OSX, except for
michael@0 324 // 0x6760 and 0x9488
michael@0 325 if (mAdapterVendorID.Equals(GfxDriverInfo::GetDeviceVendor(VendorATI), nsCaseInsensitiveStringComparator()) &&
michael@0 326 (mAdapterDeviceID.LowerCaseEqualsLiteral("0x6760") ||
michael@0 327 mAdapterDeviceID.LowerCaseEqualsLiteral("0x9488"))) {
michael@0 328 *aStatus = nsIGfxInfo::FEATURE_NO_INFO;
michael@0 329 return NS_OK;
michael@0 330 }
michael@0 331 }
michael@0 332 }
michael@0 333
michael@0 334 return GfxInfoBase::GetFeatureStatusImpl(aFeature, aStatus, aSuggestedDriverVersion, aDriverInfo, &os);
michael@0 335 }
michael@0 336
michael@0 337 #ifdef DEBUG
michael@0 338
michael@0 339 // Implement nsIGfxInfoDebug
michael@0 340
michael@0 341 /* void spoofVendorID (in DOMString aVendorID); */
michael@0 342 NS_IMETHODIMP GfxInfo::SpoofVendorID(const nsAString & aVendorID)
michael@0 343 {
michael@0 344 mAdapterVendorID = aVendorID;
michael@0 345 return NS_OK;
michael@0 346 }
michael@0 347
michael@0 348 /* void spoofDeviceID (in unsigned long aDeviceID); */
michael@0 349 NS_IMETHODIMP GfxInfo::SpoofDeviceID(const nsAString & aDeviceID)
michael@0 350 {
michael@0 351 mAdapterDeviceID = aDeviceID;
michael@0 352 return NS_OK;
michael@0 353 }
michael@0 354
michael@0 355 /* void spoofDriverVersion (in DOMString aDriverVersion); */
michael@0 356 NS_IMETHODIMP GfxInfo::SpoofDriverVersion(const nsAString & aDriverVersion)
michael@0 357 {
michael@0 358 mDriverVersion = aDriverVersion;
michael@0 359 return NS_OK;
michael@0 360 }
michael@0 361
michael@0 362 /* void spoofOSVersion (in unsigned long aVersion); */
michael@0 363 NS_IMETHODIMP GfxInfo::SpoofOSVersion(uint32_t aVersion)
michael@0 364 {
michael@0 365 mOSXVersion = aVersion;
michael@0 366 return NS_OK;
michael@0 367 }
michael@0 368
michael@0 369 #endif

mercurial