Bug 1562847 - Disable double buffering with compositor when device reset happens r=nical,bas

When double buffering is enable with compositor, DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL is used without DirectComposition. There are some devices that swap chain with DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL does not work well. In this case, device reset happens very often. To avoid the situation, the double buffering needs to be disabled when device reset happens.

Differential Revision: https://phabricator.services.mozilla.com/D36579
This commit is contained in:
sotaro
2019-07-09 06:37:45 +00:00
parent bc9aa71539
commit 04d00e3ba4
7 changed files with 41 additions and 38 deletions

View File

@@ -51,7 +51,8 @@ class gfxVarReceiver;
_(AllowD3D11KeyedMutex, bool, false) \ _(AllowD3D11KeyedMutex, bool, false) \
_(SystemTextQuality, int32_t, 5 /* CLEARTYPE_QUALITY */) \ _(SystemTextQuality, int32_t, 5 /* CLEARTYPE_QUALITY */) \
_(LayersWindowRecordingPath, nsCString, nsCString()) \ _(LayersWindowRecordingPath, nsCString, nsCString()) \
_(RemoteCanvasEnabled, bool, false) _(RemoteCanvasEnabled, bool, false) \
_(UseDoubleBufferingWithCompositor, bool, false)
/* Add new entries above this line. */ /* Add new entries above this line. */

View File

@@ -264,8 +264,7 @@ mozilla::ipc::IPCResult GPUParent::RecvInit(
} }
#ifdef XP_WIN #ifdef XP_WIN
else { else {
if (StaticPrefs::gfx_direct3d11_use_double_buffering() && if (gfxVars::UseDoubleBufferingWithCompositor()) {
IsWin10OrLater()) {
// This is needed to avoid freezing the window on a device crash on double // This is needed to avoid freezing the window on a device crash on double
// buffering, see bug 1549674. // buffering, see bug 1549674.
widget::WinCompositorWindowThread::Start(); widget::WinCompositorWindowThread::Start();

View File

@@ -485,6 +485,11 @@ void GPUProcessManager::OnRemoteProcessDeviceReset(GPUProcessHost* aHost) {
// indicating that we should give up and use software // indicating that we should give up and use software
mDeviceResetCount++; mDeviceResetCount++;
// Disable double buffering when device reset happens.
if (!gfxVars::UseWebRender() && gfxVars::UseDoubleBufferingWithCompositor()) {
gfxVars::SetUseDoubleBufferingWithCompositor(false);
}
auto newTime = TimeStamp::Now(); auto newTime = TimeStamp::Now();
auto delta = (int32_t)(newTime - mDeviceResetLastTime).ToMilliseconds(); auto delta = (int32_t)(newTime - mDeviceResetLastTime).ToMilliseconds();
mDeviceResetLastTime = newTime; mDeviceResetLastTime = newTime;

View File

@@ -201,8 +201,8 @@ bool CompositorD3D11::Initialize(nsCString* const out_failureReason) {
(IDXGIFactory2**)getter_AddRefs(dxgiFactory2)); (IDXGIFactory2**)getter_AddRefs(dxgiFactory2));
#if (_WIN32_WINDOWS_MAXVER >= 0x0A00) #if (_WIN32_WINDOWS_MAXVER >= 0x0A00)
if (StaticPrefs::gfx_direct3d11_use_double_buffering() && SUCCEEDED(hr) && if (gfxVars::UseDoubleBufferingWithCompositor() && SUCCEEDED(hr) &&
dxgiFactory2 && IsWindows10OrGreater()) { dxgiFactory2) {
// DXGI_SCALING_NONE is not available on Windows 7 with Platform Update. // DXGI_SCALING_NONE is not available on Windows 7 with Platform Update.
// This looks awful for things like the awesome bar and browser window // This looks awful for things like the awesome bar and browser window
// resizing so we don't use a flip buffer chain here. When using // resizing so we don't use a flip buffer chain here. When using

View File

@@ -234,9 +234,9 @@ bool MLGSwapChainD3D11::Initialize(CompositorWidget* aWidget) {
} }
RefPtr<IDXGIFactory2> dxgiFactory2; RefPtr<IDXGIFactory2> dxgiFactory2;
if (StaticPrefs::gfx_direct3d11_use_double_buffering() && if (gfxVars::UseDoubleBufferingWithCompositor() &&
SUCCEEDED(dxgiFactory->QueryInterface(dxgiFactory2.StartAssignment())) && SUCCEEDED(dxgiFactory->QueryInterface(dxgiFactory2.StartAssignment())) &&
dxgiFactory2 && IsWin10OrLater() && XRE_IsGPUProcess()) { dxgiFactory2 && XRE_IsGPUProcess()) {
// DXGI_SCALING_NONE is not available on Windows 7 with the Platform Update: // DXGI_SCALING_NONE is not available on Windows 7 with the Platform Update:
// This looks awful for things like the awesome bar and browser window // This looks awful for things like the awesome bar and browser window
// resizing, so we don't use a flip buffer chain here. (Note when using // resizing, so we don't use a flip buffer chain here. (Note when using

View File

@@ -1553,8 +1553,7 @@ PLayerTransactionParent* CompositorBridgeParent::AllocPLayerTransactionParent(
#ifdef XP_WIN #ifdef XP_WIN
// This is needed to avoid freezing the window on a device crash on double // This is needed to avoid freezing the window on a device crash on double
// buffering, see bug 1549674. // buffering, see bug 1549674.
if (StaticPrefs::gfx_direct3d11_use_double_buffering() && IsWin10OrLater() && if (gfxVars::UseDoubleBufferingWithCompositor() && XRE_IsGPUProcess()) {
XRE_IsGPUProcess()) {
mWidget->AsWindows()->EnsureCompositorWindow(); mWidget->AsWindows()->EnsureCompositorWindow();
} }
#endif #endif

View File

@@ -1357,8 +1357,7 @@ void gfxPlatform::WillShutdown() {
#endif #endif
} }
gfxPlatform::~gfxPlatform() { gfxPlatform::~gfxPlatform() {}
}
/* static */ /* static */
already_AddRefed<DrawTarget> gfxPlatform::CreateDrawTargetForSurface( already_AddRefed<DrawTarget> gfxPlatform::CreateDrawTargetForSurface(
@@ -2418,6 +2417,10 @@ void gfxPlatform::InitAcceleration() {
gfxCriticalNote << "Cannot evaluate keyed mutex feature status"; gfxCriticalNote << "Cannot evaluate keyed mutex feature status";
gfxVars::SetAllowD3D11KeyedMutex(true); gfxVars::SetAllowD3D11KeyedMutex(true);
} }
if (StaticPrefs::gfx_direct3d11_use_double_buffering() &&
IsWin10OrLater()) {
gfxVars::SetUseDoubleBufferingWithCompositor(true);
}
#endif #endif
} }
@@ -2613,13 +2616,12 @@ static bool CalculateWrQualifiedPrefValue() {
} }
static void HardwareTooOldForWR(FeatureState& aFeature) { static void HardwareTooOldForWR(FeatureState& aFeature) {
aFeature.Disable( aFeature.Disable(FeatureStatus::BlockedDeviceTooOld, "Device too old",
FeatureStatus::BlockedDeviceTooOld, "Device too old", NS_LITERAL_CSTRING("FEATURE_FAILURE_DEVICE_TOO_OLD"));
NS_LITERAL_CSTRING("FEATURE_FAILURE_DEVICE_TOO_OLD"));
} }
static void UpdateWRQualificationForNvidia(FeatureState& aFeature, static void UpdateWRQualificationForNvidia(FeatureState& aFeature,
int32_t aDeviceId) { int32_t aDeviceId) {
// 0x6c0 is the lowest Fermi device id. Unfortunately some Tesla // 0x6c0 is the lowest Fermi device id. Unfortunately some Tesla
// devices that don't support D3D 10.1 have higher deviceIDs. They // devices that don't support D3D 10.1 have higher deviceIDs. They
// will be included, but blocked by ANGLE. // will be included, but blocked by ANGLE.
@@ -2634,18 +2636,17 @@ static void UpdateWRQualificationForNvidia(FeatureState& aFeature,
} }
static void UpdateWRQualificationForAMD(FeatureState& aFeature, static void UpdateWRQualificationForAMD(FeatureState& aFeature,
int32_t aDeviceId) { int32_t aDeviceId) {
// AMD deviceIDs are not very well ordered. This // AMD deviceIDs are not very well ordered. This
// condition is based off the information in gpu-db // condition is based off the information in gpu-db
bool supported = bool supported = (aDeviceId >= 0x6600 && aDeviceId < 0x66b0) ||
(aDeviceId >= 0x6600 && aDeviceId < 0x66b0) || (aDeviceId >= 0x6700 && aDeviceId < 0x6720) ||
(aDeviceId >= 0x6700 && aDeviceId < 0x6720) || (aDeviceId >= 0x6780 && aDeviceId < 0x6840) ||
(aDeviceId >= 0x6780 && aDeviceId < 0x6840) || (aDeviceId >= 0x6860 && aDeviceId < 0x6880) ||
(aDeviceId >= 0x6860 && aDeviceId < 0x6880) || (aDeviceId >= 0x6900 && aDeviceId < 0x6a00) ||
(aDeviceId >= 0x6900 && aDeviceId < 0x6a00) || (aDeviceId == 0x7300) ||
(aDeviceId == 0x7300) || (aDeviceId >= 0x9830 && aDeviceId < 0x9870) ||
(aDeviceId >= 0x9830 && aDeviceId < 0x9870) || (aDeviceId >= 0x9900 && aDeviceId < 0x9a00);
(aDeviceId >= 0x9900 && aDeviceId < 0x9a00);
if (!supported) { if (!supported) {
HardwareTooOldForWR(aFeature); HardwareTooOldForWR(aFeature);
@@ -2656,15 +2657,15 @@ static void UpdateWRQualificationForAMD(FeatureState& aFeature,
// so treat the device as qualified unless it is not Windows // so treat the device as qualified unless it is not Windows
// and not nightly. // and not nightly.
#if !defined(XP_WIN) && !defined(NIGHTLY_BUILD) #if !defined(XP_WIN) && !defined(NIGHTLY_BUILD)
aFeature.Disable( aFeature.Disable(FeatureStatus::BlockedReleaseChannelAMD,
FeatureStatus::BlockedReleaseChannelAMD, "Release channel and AMD",
"Release channel and AMD", NS_LITERAL_CSTRING("FEATURE_FAILURE_RELEASE_CHANNEL_AMD"));
NS_LITERAL_CSTRING("FEATURE_FAILURE_RELEASE_CHANNEL_AMD"));
#endif // !XPWIN && !NIGHTLY_BUILD #endif // !XPWIN && !NIGHTLY_BUILD
} }
static void UpdateWRQualificationForIntel(FeatureState& aFeature, static void UpdateWRQualificationForIntel(FeatureState& aFeature,
int32_t aDeviceId, int32_t aScreenPixels) { int32_t aDeviceId,
int32_t aScreenPixels) {
const uint16_t supportedDevices[] = { const uint16_t supportedDevices[] = {
// skylake gt2+ // skylake gt2+
0x1912, 0x1912,
@@ -2776,9 +2777,8 @@ static void UpdateWRQualificationForIntel(FeatureState& aFeature,
return; return;
} }
if (aScreenPixels <= 0) { if (aScreenPixels <= 0) {
aFeature.Disable( aFeature.Disable(FeatureStatus::BlockedScreenUnknown, "Screen size unknown",
FeatureStatus::BlockedScreenUnknown, "Screen size unknown", NS_LITERAL_CSTRING("FEATURE_FAILURE_SCREEN_SIZE_UNKNOWN"));
NS_LITERAL_CSTRING("FEATURE_FAILURE_SCREEN_SIZE_UNKNOWN"));
return; return;
} }
#endif #endif
@@ -2789,10 +2789,9 @@ static void UpdateWRQualificationForIntel(FeatureState& aFeature,
// on Linux nightly. // on Linux nightly.
#else #else
// Disqualify everywhere else // Disqualify everywhere else
aFeature.Disable( aFeature.Disable(FeatureStatus::BlockedReleaseChannelIntel,
FeatureStatus::BlockedReleaseChannelIntel, "Release channel and Intel",
"Release channel and Intel", NS_LITERAL_CSTRING("FEATURE_FAILURE_RELEASE_CHANNEL_INTEL"));
NS_LITERAL_CSTRING("FEATURE_FAILURE_RELEASE_CHANNEL_INTEL"));
#endif #endif
} }
@@ -2843,7 +2842,7 @@ static FeatureState& WebRenderHardwareQualificationStatus(
const int32_t screenPixels = aScreenSize.width * aScreenSize.height; const int32_t screenPixels = aScreenSize.width * aScreenSize.height;
if (adapterVendorID == u"0x10de") { // Nvidia if (adapterVendorID == u"0x10de") { // Nvidia
UpdateWRQualificationForNvidia(featureWebRenderQualified, deviceID); UpdateWRQualificationForNvidia(featureWebRenderQualified, deviceID);
} else if (adapterVendorID == u"0x1002") { // AMD } else if (adapterVendorID == u"0x1002") { // AMD
UpdateWRQualificationForAMD(featureWebRenderQualified, deviceID); UpdateWRQualificationForAMD(featureWebRenderQualified, deviceID);