Bug 1364563 - Add a path for content process only device reset. r=dvander

This commit is contained in:
Kevin Chen 2017-07-18 23:09:00 -04:00
Родитель d4a1ddbd70
Коммит 91dc0db35c
10 изменённых файлов: 103 добавлений и 15 удалений

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

@ -21,6 +21,7 @@ struct D3D11DeviceStatus
bool textureSharingWorks;
uint32_t featureLevel;
DxgiAdapterDesc adapter;
int32_t sequenceNumber;
};
struct DevicePrefs

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

@ -516,7 +516,9 @@ ClientLayerManager::DidComposite(uint64_t aTransactionId,
if (listener) {
listener->DidCompositeWindow(aTransactionId, aCompositeStart, aCompositeEnd);
}
mTransactionIdAllocator->NotifyTransactionCompleted(aTransactionId);
if (mTransactionIdAllocator) {
mTransactionIdAllocator->NotifyTransactionCompleted(aTransactionId);
}
}
// These observers fire whether or not we were in a transaction.

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

@ -213,6 +213,8 @@ public:
virtual mozilla::ipc::IPCResult RecvStartFrameTimeRecording(const int32_t& aBufferSize, uint32_t* aOutStartIndex) override;
virtual mozilla::ipc::IPCResult RecvStopFrameTimeRecording(const uint32_t& aStartIndex, InfallibleTArray<float>* intervals) override;
virtual mozilla::ipc::IPCResult RecvCheckContentOnlyTDR(const uint32_t& sequenceNum, bool* isContentOnlyTDR) override { return IPC_OK(); }
// Unused for chrome <-> compositor communication (which this class does).
// @see CrossProcessCompositorBridgeParent::RecvRequestNotifyAfterRemotePaint
virtual mozilla::ipc::IPCResult RecvRequestNotifyAfterRemotePaint() override { return IPC_OK(); };

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

@ -10,6 +10,9 @@
#include "base/message_loop.h" // for MessageLoop
#include "base/task.h" // for CancelableTask, etc
#include "base/thread.h" // for Thread
#ifdef XP_WIN
#include "mozilla/gfx/DeviceManagerDx.h"// for DeviceManagerDx
#endif
#include "mozilla/ipc/Transport.h" // for Transport
#include "mozilla/layers/AnimationHelper.h" // for CompositorAnimationStorage
#include "mozilla/layers/APZCTreeManager.h" // for APZCTreeManager
@ -276,6 +279,29 @@ CrossProcessCompositorBridgeParent::RecvMapAndNotifyChildCreated(const uint64_t&
return IPC_FAIL_NO_REASON(this);
}
mozilla::ipc::IPCResult
CrossProcessCompositorBridgeParent::RecvCheckContentOnlyTDR(const uint32_t& sequenceNum,
bool* isContentOnlyTDR)
{
*isContentOnlyTDR = false;
#ifdef XP_WIN
ContentDeviceData compositor;
DeviceManagerDx* dm = DeviceManagerDx::Get();
// Check that the D3D11 device sequence numbers match.
D3D11DeviceStatus status;
dm->ExportDeviceInfo(&status);
if (sequenceNum == status.sequenceNumber() && !dm->HasDeviceReset()) {
*isContentOnlyTDR = true;
}
#endif
return IPC_OK();
};
void
CrossProcessCompositorBridgeParent::ShadowLayersUpdated(
LayerTransactionParent* aLayerTree,

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

@ -58,6 +58,8 @@ public:
virtual mozilla::ipc::IPCResult RecvStartFrameTimeRecording(const int32_t& aBufferSize, uint32_t* aOutStartIndex) override { return IPC_OK(); }
virtual mozilla::ipc::IPCResult RecvStopFrameTimeRecording(const uint32_t& aStartIndex, InfallibleTArray<float>* intervals) override { return IPC_OK(); }
virtual mozilla::ipc::IPCResult RecvCheckContentOnlyTDR(const uint32_t& sequenceNum, bool* isContentOnlyTDR) override;
virtual mozilla::ipc::IPCResult RecvClearApproximatelyVisibleRegions(const uint64_t& aLayersId,
const uint32_t& aPresShellId) override;

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

@ -252,6 +252,9 @@ parent:
sync PWebRenderBridge(PipelineId pipelineId, LayoutDeviceIntSize aSize)
returns (TextureFactoryIdentifier textureFactoryIdentifier, uint32_t idNamespace); //XXX: use the WrIdNamespace type
sync CheckContentOnlyTDR(uint32_t sequenceNum)
returns (bool isContentOnlyTDR);
child:
// Send back Compositor Frame Metrics from APZCs so tiled layers can
// update progressively.

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

@ -174,11 +174,6 @@ DeviceManagerDx::ImportDeviceInfo(const D3D11DeviceStatus& aDeviceStatus)
void
DeviceManagerDx::ExportDeviceInfo(D3D11DeviceStatus* aOut)
{
// Even though the parent process might not own the compositor, we still
// populate DeviceManagerDx with device statistics (for simplicity).
// That means it still gets queried for compositor information.
MOZ_ASSERT(XRE_IsParentProcess() || XRE_GetProcessType() == GeckoProcessType_GPU);
if (mDeviceStatus) {
*aOut = mDeviceStatus.value();
}
@ -322,6 +317,20 @@ DeviceManagerDx::CreateCompositorDeviceHelper(
return true;
}
// Note that it's enough for us to just use a counter for a unique ID,
// even though the counter isn't synchronized between processes. If we
// start in the GPU process and wind up in the parent process, the
// whole graphics stack is blown away anyway. But just in case, we
// make gpu process IDs negative and parent process IDs positive.
static inline int32_t
GetNextDeviceCounter()
{
static int32_t sDeviceCounter = 0;
return XRE_IsGPUProcess()
? --sDeviceCounter
: ++sDeviceCounter;
}
void
DeviceManagerDx::CreateCompositorDevice(FeatureState& d3d11)
{
@ -379,15 +388,18 @@ DeviceManagerDx::CreateCompositorDevice(FeatureState& d3d11)
D3D11Checks::WarnOnAdapterMismatch(device);
}
int featureLevel = device->GetFeatureLevel();
uint32_t featureLevel = device->GetFeatureLevel();
{
MutexAutoLock lock(mDeviceLock);
mCompositorDevice = device;
int32_t sequenceNumber = GetNextDeviceCounter();
mDeviceStatus = Some(D3D11DeviceStatus(
false,
textureSharingWorks,
featureLevel,
DxgiAdapterDesc::From(desc)));
DxgiAdapterDesc::From(desc),
sequenceNumber));
}
mCompositorDevice->SetExceptionMode(0);
}
@ -475,11 +487,14 @@ DeviceManagerDx::CreateWARPCompositorDevice()
{
MutexAutoLock lock(mDeviceLock);
mCompositorDevice = device;
int32_t sequenceNumber = GetNextDeviceCounter();
mDeviceStatus = Some(D3D11DeviceStatus(
true,
textureSharingWorks,
featureLevel,
nullAdapter));
nullAdapter,
sequenceNumber));
}
mCompositorDevice->SetExceptionMode(0);

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

@ -8,6 +8,7 @@
#include "cairo.h"
#include "mozilla/ArrayUtils.h"
#include "mozilla/layers/CompositorBridgeChild.h"
#include "gfxImageSurface.h"
#include "gfxWindowsSurface.h"
@ -20,6 +21,7 @@
#include "mozilla/WindowsVersion.h"
#include "nsServiceManagerUtils.h"
#include "nsTArray.h"
#include "nsThreadUtils.h"
#include "mozilla/Telemetry.h"
#include "GeckoProfiler.h"
@ -70,7 +72,7 @@
#include "gfxConfig.h"
#include "VsyncSource.h"
#include "DriverCrashGuard.h"
#include "mozilla/dom/ContentParent.h"
#include "mozilla/dom/ContentChild.h"
#include "mozilla/gfx/DeviceManagerDx.h"
#include "mozilla/layers/DeviceAttachmentsD3D11.h"
#include "D3D11Checks.h"
@ -894,12 +896,44 @@ gfxWindowsPlatform::SchedulePaintIfDeviceReset()
gfxCriticalNote << "(gfxWindowsPlatform) Detected device reset: " << (int)resetReason;
// Trigger an ::OnPaint for each window.
::EnumThreadWindows(GetCurrentThreadId(),
InvalidateWindowForDeviceReset,
0);
if (XRE_IsParentProcess()) {
// Trigger an ::OnPaint for each window.
::EnumThreadWindows(GetCurrentThreadId(),
InvalidateWindowForDeviceReset,
0);
} else {
NS_DispatchToMainThread(NS_NewRunnableFunction(
"gfx::gfxWindowsPlatform::SchedulePaintIfDeviceReset",
[]() -> void {
gfxWindowsPlatform::GetPlatform()->CheckForContentOnlyDeviceReset();
}
));
}
gfxCriticalNote << "(gfxWindowsPlatform) Finished device reset.";
gfxCriticalNote << "(gfxWindowsPlatform) scheduled device update.";
}
void
gfxWindowsPlatform::CheckForContentOnlyDeviceReset()
{
if (!DidRenderingDeviceReset()) {
return;
}
bool isContentOnlyTDR;
D3D11DeviceStatus status;
DeviceManagerDx::Get()->ExportDeviceInfo(&status);
CompositorBridgeChild::Get()->SendCheckContentOnlyTDR(
status.sequenceNumber(), &isContentOnlyTDR);
// The parent process doesn't know about the reset yet, or the reset is
// local to our device.
if (isContentOnlyTDR) {
gfxCriticalNote << "A content-only TDR is detected.";
dom::ContentChild* cc = dom::ContentChild::GetSingleton();
cc->RecvReinitRenderingForDeviceReset();
}
}
void

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

@ -180,6 +180,7 @@ public:
bool DidRenderingDeviceReset(DeviceResetReason* aResetReason = nullptr) override;
void SchedulePaintIfDeviceReset() override;
void CheckForContentOnlyDeviceReset();
mozilla::gfx::BackendType GetContentBackendFor(mozilla::layers::LayersBackend aLayers) override;

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

@ -993,6 +993,8 @@ description =
description =
[PCompositorBridge::PWebRenderBridge]
description =
[PCompositorBridge::CheckContentOnlyTDR]
description =
[PCompositorWidget::EnterPresentLock]
description =
platform = win