mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-27 06:43:32 +00:00
Bug 1313199 - Sync a device reset from GPU process to main process. r=dvander
--HG-- extra : rebase_source : 4daf0427fee802cd986d7439c0e27eddbf671311
This commit is contained in:
parent
fec86bdccd
commit
8ee59ed7da
@ -7,6 +7,7 @@
|
||||
#include "gfxConfig.h"
|
||||
#include "gfxPrefs.h"
|
||||
#include "GPUProcessHost.h"
|
||||
#include "GPUProcessManager.h"
|
||||
#include "mozilla/Telemetry.h"
|
||||
#include "mozilla/dom/CheckerboardReportService.h"
|
||||
#include "mozilla/gfx/gfxVars.h"
|
||||
@ -151,6 +152,13 @@ GPUChild::RecvAccumulateChildKeyedHistogram(InfallibleTArray<KeyedAccumulation>&
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
GPUChild::RecvNotifyDeviceReset()
|
||||
{
|
||||
mHost->mListener->OnProcessDeviceReset(mHost);
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
GPUChild::ActorDestroy(ActorDestroyReason aWhy)
|
||||
{
|
||||
|
@ -43,6 +43,7 @@ public:
|
||||
void ActorDestroy(ActorDestroyReason aWhy) override;
|
||||
bool RecvGraphicsError(const nsCString& aError) override;
|
||||
bool RecvNotifyUiObservers(const nsCString& aTopic) override;
|
||||
bool RecvNotifyDeviceReset() override;
|
||||
|
||||
static void Destroy(UniquePtr<GPUChild>&& aChild);
|
||||
|
||||
|
@ -114,6 +114,30 @@ GPUParent::Init(base::ProcessId aParentPid,
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
GPUParent::NotifyDeviceReset()
|
||||
{
|
||||
if (!NS_IsMainThread()) {
|
||||
NS_DispatchToMainThread(NS_NewRunnableFunction([] () -> void {
|
||||
GPUParent::GetSingleton()->NotifyDeviceReset();
|
||||
}));
|
||||
return;
|
||||
}
|
||||
|
||||
// Reset and reinitialize the compositor devices
|
||||
#ifdef XP_WIN
|
||||
if (!DeviceManagerDx::Get()->MaybeResetAndReacquireDevices()) {
|
||||
// If the device doesn't need to be reset then the device
|
||||
// has already been reset by a previous NotifyDeviceReset message.
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
// Notify the main process that there's been a device reset
|
||||
// and that they should reset their compositors and repaint
|
||||
Unused << SendNotifyDeviceReset();
|
||||
}
|
||||
|
||||
bool
|
||||
GPUParent::RecvInit(nsTArray<GfxPrefSetting>&& prefs,
|
||||
nsTArray<GfxVarUpdate>&& vars,
|
||||
|
@ -25,6 +25,7 @@ public:
|
||||
bool Init(base::ProcessId aParentPid,
|
||||
MessageLoop* aIOLoop,
|
||||
IPC::Channel* aChannel);
|
||||
void NotifyDeviceReset();
|
||||
|
||||
bool RecvInit(nsTArray<GfxPrefSetting>&& prefs,
|
||||
nsTArray<GfxVarUpdate>&& vars,
|
||||
|
@ -43,6 +43,9 @@ public:
|
||||
// Shutdown().
|
||||
virtual void OnProcessUnexpectedShutdown(GPUProcessHost* aHost)
|
||||
{}
|
||||
|
||||
virtual void OnProcessDeviceReset(GPUProcessHost* aHost)
|
||||
{}
|
||||
};
|
||||
|
||||
public:
|
||||
|
@ -257,6 +257,14 @@ GPUProcessManager::OnProcessLaunchComplete(GPUProcessHost* aHost)
|
||||
mGPUChild->SendAddLayerTreeIdMapping(mappings);
|
||||
}
|
||||
|
||||
void
|
||||
GPUProcessManager::OnProcessDeviceReset(GPUProcessHost* aHost)
|
||||
{
|
||||
for (auto& session : mRemoteSessions) {
|
||||
session->NotifyDeviceReset();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
GPUProcessManager::OnProcessUnexpectedShutdown(GPUProcessHost* aHost)
|
||||
{
|
||||
|
@ -121,6 +121,7 @@ public:
|
||||
|
||||
void OnProcessLaunchComplete(GPUProcessHost* aHost) override;
|
||||
void OnProcessUnexpectedShutdown(GPUProcessHost* aHost) override;
|
||||
void OnProcessDeviceReset(GPUProcessHost* aHost) override;
|
||||
|
||||
// Notify the GPUProcessManager that a top-level PGPU protocol has been
|
||||
// terminated. This may be called from any thread.
|
||||
|
@ -98,6 +98,8 @@ child:
|
||||
// Messages for reporting telemetry to the UI process.
|
||||
async AccumulateChildHistogram(Accumulation[] accumulations);
|
||||
async AccumulateChildKeyedHistogram(KeyedAccumulation[] accumulations);
|
||||
|
||||
async NotifyDeviceReset();
|
||||
};
|
||||
|
||||
} // namespace gfx
|
||||
|
@ -38,6 +38,13 @@ RemoteCompositorSession::~RemoteCompositorSession()
|
||||
MOZ_ASSERT(!mCompositorBridgeChild);
|
||||
}
|
||||
|
||||
void
|
||||
RemoteCompositorSession::NotifyDeviceReset()
|
||||
{
|
||||
MOZ_ASSERT(mWidget);
|
||||
mWidget->OnRenderingDeviceReset();
|
||||
}
|
||||
|
||||
void
|
||||
RemoteCompositorSession::NotifySessionLost()
|
||||
{
|
||||
|
@ -31,6 +31,7 @@ public:
|
||||
bool Reset(const nsTArray<LayersBackend>& aBackendHints, TextureFactoryIdentifier* aOutIdentifier) override;
|
||||
void Shutdown() override;
|
||||
|
||||
void NotifyDeviceReset();
|
||||
void NotifySessionLost();
|
||||
|
||||
private:
|
||||
|
@ -12,6 +12,7 @@
|
||||
#include "nsIWidget.h"
|
||||
#include "mozilla/gfx/D3D11Checks.h"
|
||||
#include "mozilla/gfx/DeviceManagerDx.h"
|
||||
#include "mozilla/gfx/GPUParent.h"
|
||||
#include "mozilla/layers/ImageHost.h"
|
||||
#include "mozilla/layers/ContentHost.h"
|
||||
#include "mozilla/layers/Effects.h"
|
||||
@ -992,6 +993,13 @@ CompositorD3D11::BeginFrame(const nsIntRegion& aInvalidRegion,
|
||||
gfxCriticalNote << "GFX: D3D11 skip BeginFrame with device-removed.";
|
||||
ReadUnlockTextures();
|
||||
*aRenderBoundsOut = IntRect();
|
||||
|
||||
// If we are in the GPU process then the main process doesn't
|
||||
// know that a device reset has happened and needs to be informed
|
||||
if (XRE_IsGPUProcess()) {
|
||||
GPUParent::GetSingleton()->NotifyDeviceReset();
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -582,6 +582,32 @@ DeviceManagerDx::ResetDevices()
|
||||
Factory::SetDirect3D11Device(nullptr);
|
||||
}
|
||||
|
||||
bool
|
||||
DeviceManagerDx::MaybeResetAndReacquireDevices()
|
||||
{
|
||||
DeviceResetReason resetReason;
|
||||
if (!GetAnyDeviceRemovedReason(&resetReason)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
Telemetry::Accumulate(Telemetry::DEVICE_RESET_REASON, uint32_t(resetReason));
|
||||
|
||||
bool createCompositorDevice = !!mCompositorDevice;
|
||||
bool createContentDevice = !!mContentDevice;
|
||||
|
||||
ResetDevices();
|
||||
|
||||
if (createCompositorDevice && !CreateCompositorDevices()) {
|
||||
// Just stop, don't try anything more
|
||||
return true;
|
||||
}
|
||||
if (createContentDevice) {
|
||||
CreateContentDevices();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
DeviceManagerDx::ContentAdapterIsParentAdapter(ID3D11Device* device)
|
||||
{
|
||||
|
@ -80,6 +80,11 @@ public:
|
||||
// a failure.
|
||||
bool GetAnyDeviceRemovedReason(DeviceResetReason* aOutReason);
|
||||
|
||||
// Reset and reacquire the devices if a reset has happened.
|
||||
// Returns whether a reset occurred not whether reacquiring
|
||||
// was successful.
|
||||
bool MaybeResetAndReacquireDevices();
|
||||
|
||||
// Test whether we can acquire a DXGI 1.2-compatible adapter. This should
|
||||
// only be called on startup before devices are initialized.
|
||||
bool CheckRemotePresentSupport();
|
||||
|
@ -58,6 +58,7 @@ class APZEventState;
|
||||
class CompositorSession;
|
||||
class ImageContainer;
|
||||
struct ScrollableLayerGuid;
|
||||
class RemoteCompositorSession;
|
||||
} // namespace layers
|
||||
|
||||
namespace widget {
|
||||
@ -112,6 +113,7 @@ class nsBaseWidget : public nsIWidget, public nsSupportsWeakReference
|
||||
friend class nsAutoRollup;
|
||||
friend class DispatchWheelEventOnMainThread;
|
||||
friend class mozilla::widget::InProcessCompositorWidget;
|
||||
friend class mozilla::layers::RemoteCompositorSession;
|
||||
|
||||
protected:
|
||||
typedef base::Thread Thread;
|
||||
|
Loading…
Reference in New Issue
Block a user