Bug 1365772 - Allow component alpha to be managed by blocklists. r=kats
☠☠ backed out by f86b5ef8947b ☠ ☠
authorAlexis Beingessner <a.beingessner@gmail.com>
Tue, 30 May 2017 09:25:40 -0400
changeset 364746 112d854f652d494562b3e5340ef2e262da7fee62
parent 364745 ae1a0f735603ebdc4a717fb0b9783b760bfd04a0
child 364747 f978d13e38c715cbbb49702ef2577f9e724b6d8a
push id91622
push userkwierso@gmail.com
push dateTue, 20 Jun 2017 00:34:46 +0000
treeherdermozilla-inbound@10b31e68ebf2 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerskats
bugs1365772
milestone56.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1365772 - Allow component alpha to be managed by blocklists. r=kats MozReview-Commit-ID: 5iEuUtmfkLl
gfx/config/gfxFeature.h
gfx/layers/Layers.cpp
gfx/layers/d3d11/CompositorD3D11.cpp
gfx/layers/d3d11/DeviceAttachmentsD3D11.cpp
gfx/layers/opengl/CompositorOGL.cpp
gfx/thebes/gfxPlatform.cpp
gfx/thebes/gfxPlatform.h
gfx/thebes/gfxPrefs.h
toolkit/mozapps/extensions/test/xpcshell/data/test_gfxBlacklist_OSVersion.xml
toolkit/mozapps/extensions/test/xpcshell/test_gfxBlacklist_OSVersion_match.js
toolkit/mozapps/extensions/test/xpcshell/test_gfxBlacklist_Version.js
widget/GfxInfoBase.cpp
widget/nsIGfxInfo.idl
--- a/gfx/config/gfxFeature.h
+++ b/gfx/config/gfxFeature.h
@@ -21,16 +21,17 @@ namespace gfx {
   _(D3D11_COMPOSITING,            Feature,      "Direct3D11 Compositing")         \
   _(OPENGL_COMPOSITING,           Feature,      "OpenGL Compositing")             \
   _(DIRECT2D,                     Feature,      "Direct2D")                       \
   _(D3D11_HW_ANGLE,               Feature,      "Direct3D11 hardware ANGLE")      \
   _(DIRECT_DRAW,                  Feature,      "DirectDraw")                     \
   _(GPU_PROCESS,                  Feature,      "GPU Process")                    \
   _(WEBRENDER,                    Feature,      "WebRender")                      \
   _(OMTP,                         Feature,      "Off Main Thread Painting")       \
+  _(COMPONENT_ALPHA,              Feature,      "Component Alpha")                \
   /* Add new entries above this comment */
 
 enum class Feature : uint32_t {
 #define MAKE_ENUM(name, type, desc) name,
   GFX_FEATURE_MAP(MAKE_ENUM)
 #undef MAKE_ENUM
   NumValues
 };
--- a/gfx/layers/Layers.cpp
+++ b/gfx/layers/Layers.cpp
@@ -14,16 +14,17 @@
 #include "LayerSorter.h"                // for SortLayersBy3DZOrder
 #include "LayersLogging.h"              // for AppendToString
 #include "LayerUserData.h"
 #include "ReadbackLayer.h"              // for ReadbackLayer
 #include "UnitTransforms.h"             // for ViewAs
 #include "gfxEnv.h"
 #include "gfxPlatform.h"                // for gfxPlatform
 #include "gfxPrefs.h"
+#include "gfxConfig.h"
 #include "gfxUtils.h"                   // for gfxUtils, etc
 #include "gfx2DGlue.h"
 #include "mozilla/DebugOnly.h"          // for DebugOnly
 #include "mozilla/IntegerPrintfMacros.h"
 #include "mozilla/Telemetry.h"          // for Accumulate
 #include "mozilla/ToString.h"
 #include "mozilla/gfx/2D.h"             // for DrawTarget
 #include "mozilla/gfx/BaseSize.h"       // for BaseSize
@@ -162,17 +163,17 @@ LayerManager::CreateImageContainer(Image
 {
   RefPtr<ImageContainer> container = new ImageContainer(flag);
   return container.forget();
 }
 
 bool
 LayerManager::AreComponentAlphaLayersEnabled()
 {
-  return gfxPrefs::ComponentAlphaEnabled();
+  return gfxConfig::IsEnabled(Feature::COMPONENT_ALPHA);
 }
 
 /*static*/ void
 LayerManager::LayerUserDataDestroy(void* data)
 {
   delete static_cast<LayerUserData*>(data);
 }
 
--- a/gfx/layers/d3d11/CompositorD3D11.cpp
+++ b/gfx/layers/d3d11/CompositorD3D11.cpp
@@ -912,17 +912,17 @@ CompositorD3D11::DrawGeometry(const Geom
       ID3D11ShaderResourceView* srViews[3] = { sourceY->GetShaderResourceView(),
                                                sourceCb->GetShaderResourceView(),
                                                sourceCr->GetShaderResourceView() };
       mContext->PSSetShaderResources(TexSlot::Y, 3, srViews);
     }
     break;
   case EffectTypes::COMPONENT_ALPHA:
     {
-      MOZ_ASSERT(gfxPrefs::ComponentAlphaEnabled());
+      MOZ_ASSERT(gfxConfig::IsEnabled(Feature::COMPONENT_ALPHA));
       MOZ_ASSERT(mAttachments->mComponentBlendState);
       EffectComponentAlpha* effectComponentAlpha =
         static_cast<EffectComponentAlpha*>(aEffectChain.mPrimaryEffect.get());
 
       TextureSourceD3D11* sourceOnWhite = effectComponentAlpha->mOnWhite->AsSourceD3D11();
       TextureSourceD3D11* sourceOnBlack = effectComponentAlpha->mOnBlack->AsSourceD3D11();
 
       if (!sourceOnWhite || !sourceOnBlack) {
--- a/gfx/layers/d3d11/DeviceAttachmentsD3D11.cpp
+++ b/gfx/layers/d3d11/DeviceAttachmentsD3D11.cpp
@@ -171,17 +171,17 @@ DeviceAttachmentsD3D11::Initialize()
   };
   blendDesc.RenderTarget[0] = rtBlendNonPremul;
   hr = mDevice->CreateBlendState(&blendDesc, getter_AddRefs(mNonPremulBlendState));
   if (Failed(hr, "create npm blender")) {
     mInitFailureId = "FEATURE_FAILURE_D3D11_NPM_BLENDER";
     return false;
   }
 
-  if (gfxPrefs::ComponentAlphaEnabled()) {
+  if (gfxConfig::IsEnabled(Feature::COMPONENT_ALPHA)) {
     D3D11_RENDER_TARGET_BLEND_DESC rtBlendComponent = {
       TRUE,
       D3D11_BLEND_ONE,
       D3D11_BLEND_INV_SRC1_COLOR,
       D3D11_BLEND_OP_ADD,
       D3D11_BLEND_ONE,
       D3D11_BLEND_INV_SRC_ALPHA,
       D3D11_BLEND_OP_ADD,
@@ -289,17 +289,17 @@ DeviceAttachmentsD3D11::CreateShaders()
   InitPixelShader(sRGBShader, mRGBShader, MaskType::MaskNone);
   InitPixelShader(sRGBShaderMask, mRGBShader, MaskType::Mask);
   InitPixelShader(sRGBAShader, mRGBAShader, MaskType::MaskNone);
   InitPixelShader(sRGBAShaderMask, mRGBAShader, MaskType::Mask);
   InitPixelShader(sYCbCrShader, mYCbCrShader, MaskType::MaskNone);
   InitPixelShader(sYCbCrShaderMask, mYCbCrShader, MaskType::Mask);
   InitPixelShader(sNV12Shader, mNV12Shader, MaskType::MaskNone);
   InitPixelShader(sNV12ShaderMask, mNV12Shader, MaskType::Mask);
-  if (gfxPrefs::ComponentAlphaEnabled()) {
+  if (gfxConfig::IsEnabled(Feature::COMPONENT_ALPHA)) {
     InitPixelShader(sComponentAlphaShader, mComponentAlphaShader, MaskType::MaskNone);
     InitPixelShader(sComponentAlphaShaderMask, mComponentAlphaShader, MaskType::Mask);
   }
 
   return mContinueInit;
 }
 
 void
--- a/gfx/layers/opengl/CompositorOGL.cpp
+++ b/gfx/layers/opengl/CompositorOGL.cpp
@@ -11,16 +11,17 @@
 #include "GLContext.h"                  // for GLContext
 #include "GLUploadHelpers.h"
 #include "Layers.h"                     // for WriteSnapshotToDumpFile
 #include "LayerScope.h"                 // for LayerScope
 #include "gfxCrashReporterUtils.h"      // for ScopedGfxFeatureReporter
 #include "gfxEnv.h"                     // for gfxEnv
 #include "gfxPlatform.h"                // for gfxPlatform
 #include "gfxPrefs.h"                   // for gfxPrefs
+#include "gfxConfig.h"
 #include "gfxRect.h"                    // for gfxRect
 #include "gfxUtils.h"                   // for gfxUtils, etc
 #include "mozilla/ArrayUtils.h"         // for ArrayLength
 #include "mozilla/Preferences.h"        // for Preferences
 #include "mozilla/gfx/BasePoint.h"      // for BasePoint
 #include "mozilla/gfx/Matrix.h"         // for Matrix4x4, Matrix
 #include "mozilla/gfx/Triangle.h"       // for Triangle
 #include "mozilla/gfx/gfxVars.h"        // for gfxVars
@@ -1409,17 +1410,17 @@ CompositorOGL::DrawGeometry(const Geomet
       // Drawing is always flipped, but when copying between surfaces we want to avoid
       // this. Pass true for the flip parameter to introduce a second flip
       // that cancels the other one out.
       didSetBlendMode = SetBlendMode(gl(), blendMode);
       BindAndDrawGeometry(program, aGeometry);
     }
     break;
   case EffectTypes::COMPONENT_ALPHA: {
-      MOZ_ASSERT(gfxPrefs::ComponentAlphaEnabled());
+      MOZ_ASSERT(gfxConfig::IsEnabled(Feature::COMPONENT_ALPHA));
       MOZ_ASSERT(blendMode == gfx::CompositionOp::OP_OVER, "Can't support blend modes with component alpha!");
       EffectComponentAlpha* effectComponentAlpha =
         static_cast<EffectComponentAlpha*>(aEffectChain.mPrimaryEffect.get());
       TextureSourceOGL* sourceOnWhite = effectComponentAlpha->mOnWhite->AsSourceOGL();
       TextureSourceOGL* sourceOnBlack = effectComponentAlpha->mOnBlack->AsSourceOGL();
 
       if (!sourceOnBlack->IsValid() ||
           !sourceOnWhite->IsValid()) {
--- a/gfx/thebes/gfxPlatform.cpp
+++ b/gfx/thebes/gfxPlatform.cpp
@@ -691,16 +691,17 @@ gfxPlatform::Init()
 #elif defined(ANDROID)
     gPlatform = new gfxAndroidPlatform;
 #else
     #error "No gfxPlatform implementation available"
 #endif
     gPlatform->InitAcceleration();
     gPlatform->InitWebRenderConfig();
     gPlatform->InitOMTPConfig();
+    gPlatform->InitComponentAlphaPrefs();
 
     if (gfxConfig::IsEnabled(Feature::GPU_PROCESS)) {
       GPUProcessManager* gpu = GPUProcessManager::Get();
       gpu->LaunchGPUProcess();
     }
 
 #ifdef USE_SKIA
     SkGraphics::Init();
@@ -2445,16 +2446,44 @@ gfxPlatform::InitOMTPConfig()
   }
 
   if (gfxConfig::IsEnabled(Feature::OMTP)) {
     gfxVars::SetUseOMTP(true);
     reporter.SetSuccessful();
   }
 }
 
+void
+gfxPlatform::InitComponentAlphaPrefs()
+{
+  FeatureState& componentAlpha = gfxConfig::GetFeature(Feature::COMPONENT_ALPHA);
+
+  // First check the about:config value
+#ifdef MOZ_GFX_OPTIMIZE_MOBILE
+  // If MOZ_GFX_OPTIMIZE_MOBILE is defined, we force component alpha off
+  // and ignore the preference.
+  componentAlpha.DisableByDefault(
+    FeatureStatus::Unavailable,
+    "Component alpha not available on mobile",
+    NS_LITERAL_CSTRING("FEATURE_FAILURE_MOBILE"));
+#else
+  componentAlpha.SetDefaultFromPref(
+    gfxPrefs::GetComponentAlphaEnabledDoNotUseDirectlyPrefName(),
+    true,
+    gfxPrefs::GetComponentAlphaEnabledDoNotUseDirectlyPrefDefault());
+#endif
+
+  // Then check the blocklist value
+  nsCString message;
+  nsCString failureId;
+  if (!IsGfxInfoStatusOkay(nsIGfxInfo::FEATURE_COMPONENT_ALPHA, &message, failureId)) {
+    componentAlpha.Disable(FeatureStatus::Blacklisted, message.get(), failureId);
+  }
+}
+
 bool
 gfxPlatform::CanUseHardwareVideoDecoding()
 {
   // this function is called from the compositor thread, so it is not
   // safe to init the prefs etc. from here.
   MOZ_ASSERT(sLayersAccelerationPrefsInitialized);
   return sLayersSupportsHardwareVideoDecoding && !sLayersHardwareVideoDecodingFailed;
 }
--- a/gfx/thebes/gfxPlatform.h
+++ b/gfx/thebes/gfxPlatform.h
@@ -823,16 +823,17 @@ private:
      * This uses nsIScreenManager to determine the screen size and color depth
      */
     void PopulateScreenInfo();
 
     void InitCompositorAccelerationPrefs();
     void InitGPUProcessPrefs();
     void InitWebRenderConfig();
     void InitOMTPConfig();
+    void InitComponentAlphaPrefs();
 
     static bool IsDXInterop2Blocked();
 
     RefPtr<gfxASurface> mScreenReferenceSurface;
     nsCOMPtr<nsIObserver> mSRGBOverrideObserver;
     nsCOMPtr<nsIObserver> mFontPrefsObserver;
     nsCOMPtr<nsIObserver> mMemoryPressureObserver;
 
--- a/gfx/thebes/gfxPrefs.h
+++ b/gfx/thebes/gfxPrefs.h
@@ -512,25 +512,17 @@ private:
   DECL_OVERRIDE_PREF(Live, "layers.advanced.table",                   LayersAllowTable, gfxPrefs::OverrideBase_WebRendest());
   DECL_OVERRIDE_PREF(Live, "layers.advanced.text-layers",             LayersAllowTextLayers, gfxPrefs::OverrideBase_WebRendest());
   DECL_GFX_PREF(Once, "layers.amd-switchable-gfx.enabled",     LayersAMDSwitchableGfxEnabled, bool, false);
   DECL_GFX_PREF(Once, "layers.async-pan-zoom.enabled",         AsyncPanZoomEnabledDoNotUseDirectly, bool, true);
   DECL_GFX_PREF(Once, "layers.async-pan-zoom.separate-event-thread", AsyncPanZoomSeparateEventThread, bool, false);
   DECL_GFX_PREF(Live, "layers.bench.enabled",                  LayersBenchEnabled, bool, false);
   DECL_GFX_PREF(Once, "layers.bufferrotation.enabled",         BufferRotationEnabled, bool, true);
   DECL_GFX_PREF(Live, "layers.child-process-shutdown",         ChildProcessShutdown, bool, true);
-#ifdef MOZ_GFX_OPTIMIZE_MOBILE
-  // If MOZ_GFX_OPTIMIZE_MOBILE is defined, we force component alpha off
-  // and ignore the preference.
-  DECL_GFX_PREF(Skip, "layers.componentalpha.enabled",         ComponentAlphaEnabled, bool, false);
-#else
-  // If MOZ_GFX_OPTIMIZE_MOBILE is not defined, we actually take the
-  // preference value, defaulting to true.
-  DECL_GFX_PREF(Once, "layers.componentalpha.enabled",         ComponentAlphaEnabled, bool, true);
-#endif
+  DECL_GFX_PREF(Once, "layers.componentalpha.enabled",         ComponentAlphaEnabledDoNotUseDirectly, bool, true);
   DECL_GFX_PREF(Live, "layers.composer2d.enabled",             Composer2DCompositionEnabled, bool, false);
   DECL_GFX_PREF(Once, "layers.d3d11.force-warp",               LayersD3D11ForceWARP, bool, false);
   DECL_GFX_PREF(Live, "layers.deaa.enabled",                   LayersDEAAEnabled, bool, false);
   DECL_GFX_PREF(Live, "layers.draw-bigimage-borders",          DrawBigImageBorders, bool, false);
   DECL_GFX_PREF(Live, "layers.draw-borders",                   DrawLayerBorders, bool, false);
   DECL_GFX_PREF(Live, "layers.draw-tile-borders",              DrawTileBorders, bool, false);
   DECL_GFX_PREF(Live, "layers.draw-layer-info",                DrawLayerInfo, bool, false);
   DECL_GFX_PREF(Live, "layers.dump",                           LayersDump, bool, false);
--- a/toolkit/mozapps/extensions/test/xpcshell/data/test_gfxBlacklist_OSVersion.xml
+++ b/toolkit/mozapps/extensions/test/xpcshell/data/test_gfxBlacklist_OSVersion.xml
@@ -23,10 +23,23 @@
         <device>0x1234</device>
         <device>0x2782</device>
       </devices>
       <feature> OPENGL_LAYERS </feature>
       <featureStatus> BLOCKED_DRIVER_VERSION </featureStatus>
       <driverVersion> 8.52.322.2202 </driverVersion>
       <driverVersionComparator> LESS_THAN </driverVersionComparator>
     </gfxBlacklistEntry>
+    <gfxBlacklistEntry>
+      <os>Darwin 13</os>
+      <vendor>0xabcd</vendor>
+      <devices>
+        <device>0x2783</device>
+        <device>0x1234</device>
+        <device>0x2782</device>
+      </devices>
+      <feature> COMPONENT_ALPHA </feature>
+      <featureStatus> BLOCKED_DRIVER_VERSION </featureStatus>
+      <driverVersion> 8.52.322.2202 </driverVersion>
+      <driverVersionComparator> LESS_THAN </driverVersionComparator>
+    </gfxBlacklistEntry>
   </gfxItems>
 </blocklist>
--- a/toolkit/mozapps/extensions/test/xpcshell/test_gfxBlacklist_OSVersion_match.js
+++ b/toolkit/mozapps/extensions/test/xpcshell/test_gfxBlacklist_OSVersion_match.js
@@ -74,16 +74,19 @@ function run_test() {
 
   function checkBlacklist() {
     if (get_platform() == "WINNT") {
       var status = gfxInfo.getFeatureStatus(Ci.nsIGfxInfo.FEATURE_DIRECT2D);
       do_check_eq(status, Ci.nsIGfxInfo.FEATURE_BLOCKED_DRIVER_VERSION);
     } else if (get_platform() == "Darwin") {
       status = gfxInfo.getFeatureStatus(Ci.nsIGfxInfo.FEATURE_OPENGL_LAYERS);
       do_check_eq(status, Ci.nsIGfxInfo.FEATURE_BLOCKED_DRIVER_VERSION);
+
+      status = gfxInfo.getFeatureStatus(Ci.nsIGfxInfo.FEATURE_COMPONENT_ALPHA);
+      do_check_eq(status, Ci.nsIGfxInfo.FEATURE_BLOCKED_DRIVER_VERSION);
     }
 
     gTestserver.stop(do_test_finished);
   }
 
   Services.obs.addObserver(function(aSubject, aTopic, aData) {
     // If we wait until after we go through the event loop, gfxInfo is sure to
     // have processed the gfxItems event.
--- a/toolkit/mozapps/extensions/test/xpcshell/test_gfxBlacklist_Version.js
+++ b/toolkit/mozapps/extensions/test/xpcshell/test_gfxBlacklist_Version.js
@@ -130,16 +130,19 @@ function run_test() {
     do_check_eq(status, Ci.nsIGfxInfo.FEATURE_STATUS_OK);
 
     status = gfxInfo.getFeatureStatus(Ci.nsIGfxInfo.FEATURE_DIRECT3D_11_ANGLE, failureId);
     do_check_eq(status, Ci.nsIGfxInfo.FEATURE_STATUS_OK);
 
     status = gfxInfo.getFeatureStatus(Ci.nsIGfxInfo.FEATURE_DX_INTEROP2, failureId);
     do_check_eq(status, Ci.nsIGfxInfo.FEATURE_STATUS_OK);
 
+    status = gfxInfo.getFeatureStatus(Ci.nsIGfxInfo.FEATURE_COMPONENT_ALPHA, failureId);
+    do_check_eq(status, Ci.nsIGfxInfo.FEATURE_STATUS_OK);
+
     gTestserver.stop(do_test_finished);
   }
 
   Services.obs.addObserver(function(aSubject, aTopic, aData) {
     // If we wait until after we go through the event loop, gfxInfo is sure to
     // have processed the gfxItems event.
     do_execute_soon(checkBlacklist);
   }, "blocklist-data-gfxItems");
--- a/widget/GfxInfoBase.cpp
+++ b/widget/GfxInfoBase.cpp
@@ -165,16 +165,19 @@ GetPrefNameForFeature(int32_t aFeature)
       name = BLACKLIST_PREF_BRANCH "webrtc.hw.acceleration.decode";
       break;
     case nsIGfxInfo::FEATURE_CANVAS2D_ACCELERATION:
       name = BLACKLIST_PREF_BRANCH "canvas2d.acceleration";
       break;
     case nsIGfxInfo::FEATURE_WEBGL2:
       name = BLACKLIST_PREF_BRANCH "webgl2";
       break;
+    case nsIGfxInfo::FEATURE_COMPONENT_ALPHA:
+      name = BLACKLIST_PREF_BRANCH "layers.componentalpha";
+      break;
     case nsIGfxInfo::FEATURE_VP8_HW_DECODE:
     case nsIGfxInfo::FEATURE_VP9_HW_DECODE:
     case nsIGfxInfo::FEATURE_DX_INTEROP2:
     case nsIGfxInfo::FEATURE_GPU_PROCESS:
       // We don't provide prefs for these features.
       break;
     default:
       MOZ_ASSERT_UNREACHABLE("Unexpected nsIGfxInfo feature?!");
@@ -345,16 +348,18 @@ BlacklistFeatureToGfxFeature(const nsASt
   else if (aFeature.EqualsLiteral("WEBRTC_HW_ACCELERATION_DECODE"))
     return nsIGfxInfo::FEATURE_WEBRTC_HW_ACCELERATION_DECODE;
   else if (aFeature.EqualsLiteral("WEBRTC_HW_ACCELERATION"))
     return nsIGfxInfo::FEATURE_WEBRTC_HW_ACCELERATION;
   else if (aFeature.EqualsLiteral("CANVAS2D_ACCELERATION"))
       return nsIGfxInfo::FEATURE_CANVAS2D_ACCELERATION;
   else if (aFeature.EqualsLiteral("WEBGL2"))
     return nsIGfxInfo::FEATURE_WEBGL2;
+  else if (aFeature.EqualsLiteral("COMPONENT_ALPHA"))
+    return nsIGfxInfo::FEATURE_COMPONENT_ALPHA;
 
   // If we don't recognize the feature, it may be new, and something
   // this version doesn't understand.  So, nothing to do.  This is
   // different from feature not being specified at all, in which case
   // this method should not get called and we should continue with the
   // "all features" blocklisting.
   return -1;
 }
@@ -975,16 +980,17 @@ GfxInfoBase::EvaluateDownloadedBlacklist
     nsIGfxInfo::FEATURE_WEBGL_ANGLE,
     nsIGfxInfo::FEATURE_WEBRTC_HW_ACCELERATION_ENCODE,
     nsIGfxInfo::FEATURE_WEBRTC_HW_ACCELERATION_DECODE,
     nsIGfxInfo::FEATURE_WEBGL_MSAA,
     nsIGfxInfo::FEATURE_STAGEFRIGHT,
     nsIGfxInfo::FEATURE_WEBRTC_HW_ACCELERATION,
     nsIGfxInfo::FEATURE_CANVAS2D_ACCELERATION,
     nsIGfxInfo::FEATURE_WEBGL2,
+    nsIGfxInfo::FEATURE_COMPONENT_ALPHA,
     0
   };
 
   // For every feature we know about, we evaluate whether this blacklist has a
   // non-STATUS_OK status. If it does, we set the pref we evaluate in
   // GetFeatureStatus above, so we don't need to hold on to this blacklist
   // anywhere permanent.
   int i = 0;
--- a/widget/nsIGfxInfo.idl
+++ b/widget/nsIGfxInfo.idl
@@ -119,18 +119,20 @@ interface nsIGfxInfo : nsISupports
   /* Whether hardware VP9 decoding is supported, starting in 48. */
   const long FEATURE_VP9_HW_DECODE = 18;
   /* Whether NV_dx_interop2 is supported, starting in 50. */
   const long FEATURE_DX_INTEROP2 = 19;
   /* Whether the GPU process is supported, starting in 52. */
   const long FEATURE_GPU_PROCESS = 20;
   /* Whether the WebGL2 is supported, starting in 54 */
   const long FEATURE_WEBGL2 = 21;
+  /* Whether per-color-component alpha (for sub-pixel-AA) is supported, starting in 56. */
+  const long FEATURE_COMPONENT_ALPHA = 22;
   /* the maximum feature value. */
-  const long FEATURE_MAX_VALUE = FEATURE_WEBGL2;
+  const long FEATURE_MAX_VALUE = FEATURE_COMPONENT_ALPHA;
 
   /*
    * A set of return values from GetFeatureStatus
    */
 
   /* The driver is safe to the best of our knowledge */
   const long FEATURE_STATUS_OK = 1;
   /* We don't know the status of the feature yet. The analysis probably hasn't finished yet. */