зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1364563 - Add a path for content process only device reset. r=dvander
This commit is contained in:
Родитель
d4a1ddbd70
Коммит
91dc0db35c
|
@ -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
|
||||
|
|
Загрузка…
Ссылка в новой задаче