Bug 1365772 - Allow component alpha to be managed by blocklists. r=kats
☠☠ backed out by 4ca3babc442d ☠ ☠
authorAlexis Beingessner <a.beingessner@gmail.com>
Tue, 30 May 2017 09:25:40 -0400
changeset 364837 66b6c25cacc7a8bc3c2d25840df837455ece3124
parent 364836 0dbc79e5d74d05b7d200e1da3927bd8d5172cca0
child 364838 3e869b1c08d0e61782cdd3deca20efc5b30713fb
push id91638
push usercbook@mozilla.com
push dateTue, 20 Jun 2017 09:31:59 +0000
treeherdermozilla-inbound@7bd4ebd905c4 [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
@@ -3,16 +3,17 @@
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "DeviceAttachmentsD3D11.h"
 #include "mozilla/Telemetry.h"
 #include "mozilla/layers/Compositor.h"
 #include "CompositorD3D11Shaders.h"
 #include "gfxPrefs.h"
+#include "gfxConfig.h"
 #include "ShaderDefinitionsD3D11.h"
 
 namespace mozilla {
 namespace layers {
 
 using namespace gfx;
 
 static const size_t kInitialMaximumTriangles = 64;
@@ -171,17 +172,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 +290,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. */