widget/cocoa/GfxInfo.mm

changeset 0
6474c204b198
     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

mercurial