Blame widget/GfxDriverInfo.h

Packit f0b94e
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
Packit f0b94e
/* This Source Code Form is subject to the terms of the Mozilla Public
Packit f0b94e
 * License, v. 2.0. If a copy of the MPL was not distributed with this
Packit f0b94e
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
Packit f0b94e
Packit f0b94e
#ifndef __mozilla_widget_GfxDriverInfo_h__
Packit f0b94e
#define __mozilla_widget_GfxDriverInfo_h__
Packit f0b94e
Packit f0b94e
#include "nsString.h"
Packit f0b94e
Packit f0b94e
// Macros for adding a blocklist item to the static list.
Packit f0b94e
#define APPEND_TO_DRIVER_BLOCKLIST(os, vendor, devices, feature,            \
Packit f0b94e
                                   featureStatus, driverComparator,         \
Packit f0b94e
                                   driverVersion, ruleId, suggestedVersion) \
Packit f0b94e
  mDriverInfo->AppendElement(GfxDriverInfo(                                 \
Packit f0b94e
      os, vendor, devices, feature, featureStatus, driverComparator,        \
Packit f0b94e
      driverVersion, ruleId, suggestedVersion))
Packit f0b94e
#define APPEND_TO_DRIVER_BLOCKLIST2(os, vendor, devices, feature,           \
Packit f0b94e
                                    featureStatus, driverComparator,        \
Packit f0b94e
                                    driverVersion, ruleId)                  \
Packit f0b94e
  mDriverInfo->AppendElement(GfxDriverInfo(os, vendor, devices, feature,    \
Packit f0b94e
                                           featureStatus, driverComparator, \
Packit f0b94e
                                           driverVersion, ruleId))
Packit f0b94e
Packit f0b94e
#define APPEND_TO_DRIVER_BLOCKLIST_RANGE(                           \
Packit f0b94e
    os, vendor, devices, feature, featureStatus, driverComparator,  \
Packit f0b94e
    driverVersion, driverVersionMax, ruleId, suggestedVersion)      \
Packit f0b94e
  do {                                                              \
Packit f0b94e
    MOZ_ASSERT(driverComparator == DRIVER_BETWEEN_EXCLUSIVE ||      \
Packit f0b94e
               driverComparator == DRIVER_BETWEEN_INCLUSIVE ||      \
Packit f0b94e
               driverComparator == DRIVER_BETWEEN_INCLUSIVE_START); \
Packit f0b94e
    GfxDriverInfo info(os, vendor, devices, feature, featureStatus, \
Packit f0b94e
                       driverComparator, driverVersion, ruleId,     \
Packit f0b94e
                       suggestedVersion);                           \
Packit f0b94e
    info.mDriverVersionMax = driverVersionMax;                      \
Packit f0b94e
    mDriverInfo->AppendElement(info);                               \
Packit f0b94e
  } while (false)
Packit f0b94e
Packit f0b94e
#define APPEND_TO_DRIVER_BLOCKLIST_RANGE_GPU2(                      \
Packit f0b94e
    os, vendor, devices, feature, featureStatus, driverComparator,  \
Packit f0b94e
    driverVersion, driverVersionMax, ruleId, suggestedVersion)      \
Packit f0b94e
  do {                                                              \
Packit f0b94e
    MOZ_ASSERT(driverComparator == DRIVER_BETWEEN_EXCLUSIVE ||      \
Packit f0b94e
               driverComparator == DRIVER_BETWEEN_INCLUSIVE ||      \
Packit f0b94e
               driverComparator == DRIVER_BETWEEN_INCLUSIVE_START); \
Packit f0b94e
    GfxDriverInfo info(os, vendor, devices, feature, featureStatus, \
Packit f0b94e
                       driverComparator, driverVersion, ruleId,     \
Packit f0b94e
                       suggestedVersion, false, true);              \
Packit f0b94e
    info.mDriverVersionMax = driverVersionMax;                      \
Packit f0b94e
    mDriverInfo->AppendElement(info);                               \
Packit f0b94e
  } while (false)
Packit f0b94e
Packit f0b94e
namespace mozilla {
Packit f0b94e
namespace widget {
Packit f0b94e
Packit f0b94e
enum class OperatingSystem {
Packit f0b94e
  Unknown,
Packit f0b94e
  Windows,
Packit f0b94e
  WindowsXP,
Packit f0b94e
  WindowsServer2003,
Packit f0b94e
  WindowsVista,
Packit f0b94e
  Windows7,
Packit f0b94e
  Windows8,
Packit f0b94e
  Windows8_1,
Packit f0b94e
  Windows10,
Packit f0b94e
  Linux,
Packit f0b94e
  OSX,
Packit f0b94e
  OSX10_5,
Packit f0b94e
  OSX10_6,
Packit f0b94e
  OSX10_7,
Packit f0b94e
  OSX10_8,
Packit f0b94e
  OSX10_9,
Packit f0b94e
  OSX10_10,
Packit f0b94e
  OSX10_11,
Packit f0b94e
  OSX10_12,
Packit f0b94e
  OSX10_13,
Packit f0b94e
  Android,
Packit f0b94e
  Ios
Packit f0b94e
};
Packit f0b94e
Packit f0b94e
enum VersionComparisonOp {
Packit f0b94e
  DRIVER_LESS_THAN,                    // driver <  version
Packit f0b94e
  DRIVER_BUILD_ID_LESS_THAN,           // driver build id <  version
Packit f0b94e
  DRIVER_LESS_THAN_OR_EQUAL,           // driver <= version
Packit f0b94e
  DRIVER_BUILD_ID_LESS_THAN_OR_EQUAL,  // driver build id <= version
Packit f0b94e
  DRIVER_GREATER_THAN,                 // driver >  version
Packit f0b94e
  DRIVER_GREATER_THAN_OR_EQUAL,        // driver >= version
Packit f0b94e
  DRIVER_EQUAL,                        // driver == version
Packit f0b94e
  DRIVER_NOT_EQUAL,                    // driver != version
Packit f0b94e
  DRIVER_BETWEEN_EXCLUSIVE,        // driver > version && driver < versionMax
Packit f0b94e
  DRIVER_BETWEEN_INCLUSIVE,        // driver >= version && driver <= versionMax
Packit f0b94e
  DRIVER_BETWEEN_INCLUSIVE_START,  // driver >= version && driver < versionMax
Packit f0b94e
  DRIVER_COMPARISON_IGNORED
Packit f0b94e
};
Packit f0b94e
Packit f0b94e
enum DeviceFamily {
Packit f0b94e
  IntelGMA500,
Packit f0b94e
  IntelGMA900,
Packit f0b94e
  IntelGMA950,
Packit f0b94e
  IntelGMA3150,
Packit f0b94e
  IntelGMAX3000,
Packit f0b94e
  IntelGMAX4500HD,
Packit f0b94e
  IntelHDGraphicsToSandyBridge,
Packit f0b94e
  IntelHD3000,
Packit f0b94e
  IntelMobileHDGraphics,
Packit f0b94e
  NvidiaBlockD3D9Layers,
Packit f0b94e
  RadeonX1000,
Packit f0b94e
  Geforce7300GT,
Packit f0b94e
  Nvidia310M,
Packit f0b94e
  Nvidia8800GTS,
Packit f0b94e
  Bug1137716,
Packit f0b94e
  Bug1116812,
Packit f0b94e
  Bug1155608,
Packit f0b94e
  Bug1207665,
Packit f0b94e
  Bug1447141,
Packit f0b94e
  DeviceFamilyMax
Packit f0b94e
};
Packit f0b94e
Packit f0b94e
enum DeviceVendor {
Packit f0b94e
  VendorAll,  // There is an assumption that this is the first enum
Packit f0b94e
  VendorIntel,
Packit f0b94e
  VendorNVIDIA,
Packit f0b94e
  VendorAMD,
Packit f0b94e
  VendorATI,
Packit f0b94e
  VendorMicrosoft,
Packit f0b94e
  VendorParallels,
Packit f0b94e
  VendorQualcomm,
Packit f0b94e
  DeviceVendorMax
Packit f0b94e
};
Packit f0b94e
Packit f0b94e
/* Array of devices to match, or an empty array for all devices */
Packit f0b94e
typedef nsTArray<nsString> GfxDeviceFamily;
Packit f0b94e
Packit f0b94e
struct GfxDriverInfo {
Packit f0b94e
  // If |ownDevices| is true, you are transferring ownership of the devices
Packit f0b94e
  // array, and it will be deleted when this GfxDriverInfo is destroyed.
Packit f0b94e
  GfxDriverInfo(OperatingSystem os, nsAString &vendor, GfxDeviceFamily *devices,
Packit f0b94e
                int32_t feature, int32_t featureStatus, VersionComparisonOp op,
Packit f0b94e
                uint64_t driverVersion, const char *ruleId,
Packit f0b94e
                const char *suggestedVersion = nullptr, bool ownDevices = false,
Packit f0b94e
                bool gpu2 = false);
Packit f0b94e
Packit f0b94e
  GfxDriverInfo();
Packit f0b94e
  GfxDriverInfo(const GfxDriverInfo &);
Packit f0b94e
  ~GfxDriverInfo();
Packit f0b94e
Packit f0b94e
  OperatingSystem mOperatingSystem;
Packit f0b94e
  uint32_t mOperatingSystemVersion;
Packit f0b94e
Packit f0b94e
  nsString mAdapterVendor;
Packit f0b94e
Packit f0b94e
  static GfxDeviceFamily *const allDevices;
Packit f0b94e
  GfxDeviceFamily *mDevices;
Packit f0b94e
Packit f0b94e
  // Whether the mDevices array should be deleted when this structure is
Packit f0b94e
  // deallocated. False by default.
Packit f0b94e
  bool mDeleteDevices;
Packit f0b94e
Packit f0b94e
  /* A feature from nsIGfxInfo, or all features */
Packit f0b94e
  int32_t mFeature;
Packit f0b94e
  static int32_t allFeatures;
Packit f0b94e
Packit f0b94e
  /* A feature status from nsIGfxInfo */
Packit f0b94e
  int32_t mFeatureStatus;
Packit f0b94e
Packit f0b94e
  VersionComparisonOp mComparisonOp;
Packit f0b94e
Packit f0b94e
  /* versions are assumed to be A.B.C.D packed as 0xAAAABBBBCCCCDDDD */
Packit f0b94e
  uint64_t mDriverVersion;
Packit f0b94e
  uint64_t mDriverVersionMax;
Packit f0b94e
  static uint64_t allDriverVersions;
Packit f0b94e
Packit f0b94e
  const char *mSuggestedVersion;
Packit f0b94e
  nsCString mRuleId;
Packit f0b94e
Packit f0b94e
  static const GfxDeviceFamily *GetDeviceFamily(DeviceFamily id);
Packit f0b94e
  static GfxDeviceFamily *mDeviceFamilies[DeviceFamilyMax];
Packit f0b94e
Packit f0b94e
  static const nsAString &GetDeviceVendor(DeviceVendor id);
Packit f0b94e
  static nsAString *mDeviceVendors[DeviceVendorMax];
Packit f0b94e
Packit f0b94e
  nsString mModel, mHardware, mProduct, mManufacturer;
Packit f0b94e
Packit f0b94e
  bool mGpu2;
Packit f0b94e
};
Packit f0b94e
Packit f0b94e
#define GFX_DRIVER_VERSION(a, b, c, d)                               \
Packit f0b94e
  ((uint64_t(a) << 48) | (uint64_t(b) << 32) | (uint64_t(c) << 16) | \
Packit f0b94e
   uint64_t(d))
Packit f0b94e
Packit f0b94e
inline uint64_t V(uint32_t a, uint32_t b, uint32_t c, uint32_t d) {
Packit f0b94e
  // We make sure every driver number is padded by 0s, this will allow us the
Packit f0b94e
  // easiest 'compare as if decimals' approach. See ParseDriverVersion for a
Packit f0b94e
  // more extensive explanation of this approach.
Packit f0b94e
  while (b > 0 && b < 1000) {
Packit f0b94e
    b *= 10;
Packit f0b94e
  }
Packit f0b94e
  while (c > 0 && c < 1000) {
Packit f0b94e
    c *= 10;
Packit f0b94e
  }
Packit f0b94e
  while (d > 0 && d < 1000) {
Packit f0b94e
    d *= 10;
Packit f0b94e
  }
Packit f0b94e
  return GFX_DRIVER_VERSION(a, b, c, d);
Packit f0b94e
}
Packit f0b94e
Packit f0b94e
// All destination string storage needs to have at least 5 bytes available.
Packit f0b94e
inline bool SplitDriverVersion(const char *aSource, char *aAStr, char *aBStr,
Packit f0b94e
                               char *aCStr, char *aDStr) {
Packit f0b94e
  // sscanf doesn't do what we want here to we parse this manually.
Packit f0b94e
  int len = strlen(aSource);
Packit f0b94e
Packit f0b94e
  // This "4" is hardcoded in a few places, including once as a 3.
Packit f0b94e
  char *dest[4] = {aAStr, aBStr, aCStr, aDStr};
Packit f0b94e
  unsigned destIdx = 0;
Packit f0b94e
  unsigned destPos = 0;
Packit f0b94e
Packit f0b94e
  for (int i = 0; i < len; i++) {
Packit f0b94e
    if (destIdx >= 4) {
Packit f0b94e
      // Invalid format found. Ensure we don't access dest beyond bounds.
Packit f0b94e
      return false;
Packit f0b94e
    }
Packit f0b94e
Packit f0b94e
    if (aSource[i] == '.') {
Packit f0b94e
      MOZ_ASSERT(destIdx < 4 && destPos <= 4);
Packit f0b94e
      dest[destIdx++][destPos] = 0;
Packit f0b94e
      destPos = 0;
Packit f0b94e
      continue;
Packit f0b94e
    }
Packit f0b94e
Packit f0b94e
    if (destPos > 3) {
Packit f0b94e
      // Ignore more than 4 chars. Ensure we never access dest[destIdx]
Packit f0b94e
      // beyond its bounds.
Packit f0b94e
      continue;
Packit f0b94e
    }
Packit f0b94e
Packit f0b94e
    MOZ_ASSERT(destIdx < 4 && destPos < 4);
Packit f0b94e
    dest[destIdx][destPos++] = aSource[i];
Packit f0b94e
  }
Packit f0b94e
Packit f0b94e
  // Take care of the trailing period
Packit f0b94e
  if (destIdx >= 4) {
Packit f0b94e
    return false;
Packit f0b94e
  }
Packit f0b94e
Packit f0b94e
  // Add last terminator.
Packit f0b94e
  MOZ_ASSERT(destIdx < 4 && destPos <= 4);
Packit f0b94e
  dest[destIdx][destPos] = 0;
Packit f0b94e
Packit f0b94e
  if (destIdx != 3) {
Packit f0b94e
    return false;
Packit f0b94e
  }
Packit f0b94e
  return true;
Packit f0b94e
}
Packit f0b94e
Packit f0b94e
// This allows us to pad driver version 'substrings' with 0s, this
Packit f0b94e
// effectively allows us to treat the version numbers as 'decimals'. This is
Packit f0b94e
// a little strange but this method seems to do the right thing for all
Packit f0b94e
// different vendor's driver strings. i.e. .98 will become 9800, which is
Packit f0b94e
// larger than .978 which would become 9780.
Packit f0b94e
inline void PadDriverDecimal(char *aString) {
Packit f0b94e
  for (int i = 0; i < 4; i++) {
Packit f0b94e
    if (!aString[i]) {
Packit f0b94e
      for (int c = i; c < 4; c++) {
Packit f0b94e
        aString[c] = '0';
Packit f0b94e
      }
Packit f0b94e
      break;
Packit f0b94e
    }
Packit f0b94e
  }
Packit f0b94e
  aString[4] = 0;
Packit f0b94e
}
Packit f0b94e
Packit f0b94e
inline bool ParseDriverVersion(const nsAString &aVersion,
Packit f0b94e
                               uint64_t *aNumericVersion) {
Packit f0b94e
  *aNumericVersion = 0;
Packit f0b94e
Packit f0b94e
#if defined(XP_WIN)
Packit f0b94e
  int a, b, c, d;
Packit f0b94e
  char aStr[8], bStr[8], cStr[8], dStr[8];
Packit f0b94e
  /* honestly, why do I even bother */
Packit f0b94e
  if (!SplitDriverVersion(NS_LossyConvertUTF16toASCII(aVersion).get(), aStr,
Packit f0b94e
                          bStr, cStr, dStr))
Packit f0b94e
    return false;
Packit f0b94e
Packit f0b94e
  PadDriverDecimal(bStr);
Packit f0b94e
  PadDriverDecimal(cStr);
Packit f0b94e
  PadDriverDecimal(dStr);
Packit f0b94e
Packit f0b94e
  a = atoi(aStr);
Packit f0b94e
  b = atoi(bStr);
Packit f0b94e
  c = atoi(cStr);
Packit f0b94e
  d = atoi(dStr);
Packit f0b94e
Packit f0b94e
  if (a < 0 || a > 0xffff) return false;
Packit f0b94e
  if (b < 0 || b > 0xffff) return false;
Packit f0b94e
  if (c < 0 || c > 0xffff) return false;
Packit f0b94e
  if (d < 0 || d > 0xffff) return false;
Packit f0b94e
Packit f0b94e
  *aNumericVersion = GFX_DRIVER_VERSION(a, b, c, d);
Packit f0b94e
  MOZ_ASSERT(*aNumericVersion != GfxDriverInfo::allDriverVersions);
Packit f0b94e
  return true;
Packit f0b94e
#elif defined(ANDROID)
Packit f0b94e
  // Can't use aVersion.ToInteger() because that's not compiled into our code
Packit f0b94e
  // unless we have XPCOM_GLUE_AVOID_NSPR disabled.
Packit f0b94e
  *aNumericVersion = atoi(NS_LossyConvertUTF16toASCII(aVersion).get());
Packit f0b94e
  MOZ_ASSERT(*aNumericVersion != GfxDriverInfo::allDriverVersions);
Packit f0b94e
  return true;
Packit f0b94e
#else
Packit f0b94e
  return false;
Packit f0b94e
#endif
Packit f0b94e
}
Packit f0b94e
Packit f0b94e
}  // namespace widget
Packit f0b94e
}  // namespace mozilla
Packit f0b94e
Packit f0b94e
#endif /*__mozilla_widget_GfxDriverInfo_h__ */