Bug 1785366 - Blocklist backdrop filter on some Ivy/Sandybridge Intel Windows drivers. r=jrmuizel,emilio

Backdrop filter crashes newer Intel drivers on Windows. This patch adds
support to the blocklist infrastructure for backdrop filter, and hooks
this up with the CSS property table.

Differential Revision: https://phabricator.services.mozilla.com/D154950
This commit is contained in:
Andrew Osmond 2022-08-18 03:21:27 +00:00
Родитель cd56c8b9ae
Коммит 96648c7055
9 изменённых файлов: 128 добавлений и 6 удалений

Просмотреть файл

@ -45,7 +45,8 @@ namespace gfx {
_(VP8_HW_DECODE, Feature, "VP8 hardware decoding") \
_(VP9_HW_DECODE, Feature, "VP9 hardware decoding") \
_(DMABUF_SURFACE_EXPORT, Feature, "WebGL DMABuf surface export") \
_(REUSE_DECODER_DEVICE, Feature, "Reuse decoder device")
_(REUSE_DECODER_DEVICE, Feature, "Reuse decoder device") \
_(BACKDROP_FILTER, Feature, "Backdrop filter")
/* Add new entries above this comment */
enum class Feature : uint32_t {
@ -105,6 +106,9 @@ class FeatureState {
bool DisabledByDefault() const;
// Clear all state.
void Reset();
private:
void SetUser(FeatureStatus aStatus, const char* aMessage,
const nsACString& aFailureId);
@ -118,9 +122,6 @@ class FeatureState {
void AssertInitialized() const { MOZ_ASSERT(IsInitialized()); }
// Clear all state.
void Reset();
private:
struct Instance {
char mMessage[64];

Просмотреть файл

@ -93,7 +93,8 @@ class gfxVarReceiver;
_(HwDecodedVideoZeroCopy, bool, false) \
_(UseDMABufSurfaceExport, bool, true) \
_(ReuseDecoderDevice, bool, false) \
_(UseCanvasRenderThread, bool, false)
_(UseCanvasRenderThread, bool, false) \
_(AllowBackdropFilter, bool, false)
/* Add new entries above this line. */

Просмотреть файл

@ -921,6 +921,7 @@ void gfxPlatform::Init() {
gPlatform->InitWebGLConfig();
gPlatform->InitWebGPUConfig();
gPlatform->InitWindowOcclusionConfig();
gPlatform->InitBackdropFilterConfig();
// When using WebRender, we defer initialization of the D3D11 devices until
// the (rare) cases where they're used. Note that the GPU process where
@ -3041,6 +3042,54 @@ void gfxPlatform::InitWindowOcclusionConfig() {
#endif
}
static void BackdropFilterPrefChangeCallback(const char*, void*) {
FeatureState& feature = gfxConfig::GetFeature(Feature::BACKDROP_FILTER);
// We need to reset because the user status needs to be set before the
// environment status, but the environment status comes from the blocklist,
// and the user status can be updated after the fact.
feature.Reset();
feature.EnableByDefault();
if (StaticPrefs::layout_css_backdrop_filter_force_enabled()) {
feature.UserForceEnable("Force enabled by pref");
}
nsCString message;
nsCString failureId;
if (!gfxPlatform::IsGfxInfoStatusOkay(nsIGfxInfo::FEATURE_BACKDROP_FILTER,
&message, failureId)) {
feature.Disable(FeatureStatus::Blocklisted, message.get(), failureId);
}
// This may still be gated by the layout.css.backdrop-filter.enabled pref but
// the test infrastructure is very sensitive to how changes to that pref
// propagate, so we don't include them in the gfxVars/gfxFeature.
gfxVars::SetAllowBackdropFilter(feature.IsEnabled());
}
void gfxPlatform::InitBackdropFilterConfig() {
// This would ideally be in the nsCSSProps code
// but nsCSSProps is initialized before gfxPlatform
// so it has to be done here.
gfxVars::AddReceiver(&nsCSSProps::GfxVarReceiver());
if (!XRE_IsParentProcess()) {
// gfxVars doesn't notify receivers when initialized on content processes
// we need to explicitly recompute backdrop-filter's enabled state here.
nsCSSProps::RecomputeEnabledState(
StaticPrefs::GetPrefName_layout_css_backdrop_filter_enabled());
return;
}
BackdropFilterPrefChangeCallback(nullptr, nullptr);
Preferences::RegisterCallback(
BackdropFilterPrefChangeCallback,
nsDependentCString(
StaticPrefs::GetPrefName_layout_css_backdrop_filter_force_enabled()));
}
bool gfxPlatform::CanUseHardwareVideoDecoding() {
// this function is called from the compositor thread, so it is not
// safe to init the prefs etc. from here.

Просмотреть файл

@ -822,6 +822,7 @@ class gfxPlatform : public mozilla::layers::MemoryPressureListener {
virtual void InitWebGLConfig();
virtual void InitWebGPUConfig();
virtual void InitWindowOcclusionConfig();
void InitBackdropFilterConfig();
virtual void GetPlatformDisplayInfo(mozilla::widget::InfoObject& aObj) {}

Просмотреть файл

@ -87,6 +87,10 @@ void nsCSSProps::RecomputeEnabledState(const char* aPref, void*) {
gPropertyEnabled[pref->mPropID] = true;
#else
gPropertyEnabled[pref->mPropID] = Preferences::GetBool(pref->mPref);
if (pref->mPropID == eCSSProperty_backdrop_filter) {
gPropertyEnabled[pref->mPropID] &=
gfx::gfxVars::GetAllowBackdropFilterOrDefault();
}
#endif
}
}
@ -218,4 +222,41 @@ bool nsCSSProps::gPropertyEnabled[eCSSProperty_COUNT_with_aliases] = {
#undef IS_ENABLED_BY_DEFAULT
};
/**
* A singleton class to register as a receiver for gfxVars.
* Updates the state of backdrop-filter's pref if the gfx
* backdrop filter var changes state.
*/
class nsCSSPropsGfxVarReceiver final : public gfx::gfxVarReceiver {
constexpr nsCSSPropsGfxVarReceiver() = default;
// Backdrop filter's last known enabled state.
static bool sLastKnownAllowBackdropFilter;
static nsCSSPropsGfxVarReceiver sInstance;
public:
static gfx::gfxVarReceiver& GetInstance() { return sInstance; }
void OnVarChanged(const gfx::GfxVarUpdate&) override {
bool enabled = gfx::gfxVars::AllowBackdropFilter();
if (sLastKnownAllowBackdropFilter != enabled) {
sLastKnownAllowBackdropFilter = enabled;
nsCSSProps::RecomputeEnabledState(
StaticPrefs::GetPrefName_layout_css_backdrop_filter_enabled());
}
}
};
/* static */
nsCSSPropsGfxVarReceiver nsCSSPropsGfxVarReceiver::sInstance =
nsCSSPropsGfxVarReceiver();
/* static */
bool nsCSSPropsGfxVarReceiver::sLastKnownAllowBackdropFilter = false;
/* static */
gfx::gfxVarReceiver& nsCSSProps::GfxVarReceiver() {
return nsCSSPropsGfxVarReceiver::GetInstance();
}
#include "nsCSSPropsGenerated.inc"

Просмотреть файл

@ -7790,6 +7790,12 @@
value: true
mirror: always
# Do we override the blocklist for CSS backdrop-filter?
- name: layout.css.backdrop-filter.force-enabled
type: bool
value: false
mirror: always
# Should stray control characters be rendered visibly?
- name: layout.css.control-characters.visible
type: RelaxedAtomicBool

Просмотреть файл

@ -257,6 +257,9 @@ static const char* GetPrefNameForFeature(int32_t aFeature) {
case nsIGfxInfo::FEATURE_REUSE_DECODER_DEVICE:
name = BLOCKLIST_PREF_BRANCH "reuse-decoder-device";
break;
case nsIGfxInfo::FEATURE_BACKDROP_FILTER:
name = BLOCKLIST_PREF_BRANCH "backdrop.filter";
break;
default:
MOZ_ASSERT_UNREACHABLE("Unexpected nsIGfxInfo feature?!");
break;
@ -522,6 +525,9 @@ static int32_t BlocklistFeatureToGfxFeature(const nsAString& aFeature) {
if (aFeature.EqualsLiteral("WEBRENDER_PARTIAL_PRESENT")) {
return nsIGfxInfo::FEATURE_WEBRENDER_PARTIAL_PRESENT;
}
if (aFeature.EqualsLiteral("BACKDROP_FILTER")) {
return nsIGfxInfo::FEATURE_BACKDROP_FILTER;
}
// If we don't recognize the feature, it may be new, and something
// this version doesn't understand. So, nothing to do. This is
@ -1402,6 +1408,7 @@ void GfxInfoBase::EvaluateDownloadedBlocklist(
nsIGfxInfo::FEATURE_HW_DECODED_VIDEO_ZERO_COPY,
nsIGfxInfo::FEATURE_REUSE_DECODER_DEVICE,
nsIGfxInfo::FEATURE_WEBRENDER_PARTIAL_PRESENT,
nsIGfxInfo::FEATURE_BACKDROP_FILTER,
0};
// For every feature we know about, we evaluate whether this blocklist has a

Просмотреть файл

@ -179,8 +179,10 @@ interface nsIGfxInfo : nsISupports
const long FEATURE_DMABUF_SURFACE_EXPORT = 40;
/* Whether reuse decoder device is supported, starting in 104. */
const long FEATURE_REUSE_DECODER_DEVICE = 41;
/* Whether to allow backdrop filter, starting in 105. */
const long FEATURE_BACKDROP_FILTER = 42;
/* the maximum feature value. */
const long FEATURE_MAX_VALUE = FEATURE_REUSE_DECODER_DEVICE;
const long FEATURE_MAX_VALUE = FEATURE_BACKDROP_FILTER;
/*
* A set of return values from GetFeatureStatus

Просмотреть файл

@ -1188,6 +1188,9 @@ static bool OnlyAllowFeatureOnWhitelistedVendor(int32_t aFeature) {
// Remote WebGL is needed for Win32k Lockdown, so it should be enabled
// regardless of HW support or not
case nsIGfxInfo::FEATURE_ALLOW_WEBGL_OUT_OF_PROCESS:
// Backdrop filter should generally work, especially if we fall back to
// Software WebRender because of an unknown vendor.
case nsIGfxInfo::FEATURE_BACKDROP_FILTER:
return false;
default:
return true;
@ -1871,6 +1874,17 @@ const nsTArray<GfxDriverInfo>& GfxInfo::GetGfxDriverInfo() {
nsIGfxInfo::FEATURE_WEBRENDER_SCISSORED_CACHE_CLEARS,
nsIGfxInfo::FEATURE_BLOCKED_DEVICE, DRIVER_COMPARISON_IGNORED,
V(0, 0, 0, 0), "FEATURE_FAILURE_BUG_1603515");
////////////////////////////////////
// FEATURE_BACKDROP_FILTER
// Backdrop filter crashes the driver. See bug 1785366 and bug 1784093.
APPEND_TO_DRIVER_BLOCKLIST_RANGE(
OperatingSystem::Windows, DeviceFamily::IntelHDGraphicsToIvyBridge,
nsIGfxInfo::FEATURE_BACKDROP_FILTER,
nsIGfxInfo::FEATURE_BLOCKED_DRIVER_VERSION, DRIVER_BETWEEN_EXCLUSIVE,
V(8, 15, 10, 2879), V(10, 18, 10, 4425), "FEATURE_FAILURE_BUG_1785366",
"Intel driver >= 10.18.10.4425");
}
return *sDriverInfo;
}