зеркало из https://github.com/mozilla/gecko-dev.git
Don't reset devices for each tab when the compositor resets. (bug 1316788, r=rhunt)
This commit is contained in:
Родитель
c7859ea378
Коммит
2c5e03e62e
|
@ -3003,8 +3003,6 @@ TabChild::ReinitRendering()
|
|||
void
|
||||
TabChild::CompositorUpdated(const TextureFactoryIdentifier& aNewIdentifier)
|
||||
{
|
||||
gfxPlatform::GetPlatform()->CompositorUpdated();
|
||||
|
||||
RefPtr<LayerManager> lm = mPuppetWidget->GetLayerManager();
|
||||
ClientLayerManager* clm = lm->AsClientLayerManager();
|
||||
MOZ_ASSERT(clm);
|
||||
|
|
|
@ -45,6 +45,7 @@ public:
|
|||
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(CompositorSession)
|
||||
|
||||
virtual bool Reset(const nsTArray<LayersBackend>& aBackendHints,
|
||||
uint64_t aSeqNo,
|
||||
TextureFactoryIdentifier* aOutIdentifier) = 0;
|
||||
|
||||
virtual void Shutdown() = 0;
|
||||
|
|
|
@ -60,6 +60,7 @@ GPUProcessManager::Shutdown()
|
|||
GPUProcessManager::GPUProcessManager()
|
||||
: mTaskFactory(this),
|
||||
mNextLayerTreeId(0),
|
||||
mNextResetSequenceNo(0),
|
||||
mNumProcessAttempts(0),
|
||||
mDeviceResetCount(0),
|
||||
mProcess(nullptr),
|
||||
|
@ -306,10 +307,12 @@ GPUProcessManager::OnProcessDeviceReset(GPUProcessHost* aHost)
|
|||
HandleProcessLost();
|
||||
return;
|
||||
}
|
||||
|
||||
uint64_t seqNo = GetNextDeviceResetSequenceNumber();
|
||||
|
||||
// We're good, do a reset like normal
|
||||
for (auto& session : mRemoteSessions) {
|
||||
session->NotifyDeviceReset();
|
||||
session->NotifyDeviceReset(seqNo);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -148,6 +148,14 @@ public:
|
|||
return mNumProcessAttempts > 0;
|
||||
}
|
||||
|
||||
// Returns the next compositor reset sequence number, a monotonic counter
|
||||
// for when the compositing device resets. Since content processes are
|
||||
// notified of resets through each individual tab, this allows content to
|
||||
// only re-acquire devices once for each reset.
|
||||
uint64_t GetNextDeviceResetSequenceNumber() {
|
||||
return ++mNextResetSequenceNo;
|
||||
}
|
||||
|
||||
private:
|
||||
// Called from our xpcom-shutdown observer.
|
||||
void OnXPCOMShutdown();
|
||||
|
@ -213,6 +221,7 @@ private:
|
|||
ipc::TaskFactory<GPUProcessManager> mTaskFactory;
|
||||
RefPtr<VsyncIOThreadHolder> mVsyncIOThread;
|
||||
uint64_t mNextLayerTreeId;
|
||||
uint64_t mNextResetSequenceNo;
|
||||
uint32_t mNumProcessAttempts;
|
||||
|
||||
nsTArray<RefPtr<RemoteCompositorSession>> mRemoteSessions;
|
||||
|
|
|
@ -61,9 +61,11 @@ InProcessCompositorSession::GetAPZCTreeManager() const
|
|||
}
|
||||
|
||||
bool
|
||||
InProcessCompositorSession::Reset(const nsTArray<LayersBackend>& aBackendHints, TextureFactoryIdentifier* aOutIdentifier)
|
||||
InProcessCompositorSession::Reset(const nsTArray<LayersBackend>& aBackendHints,
|
||||
uint64_t aSeqNo,
|
||||
TextureFactoryIdentifier* aOutIdentifier)
|
||||
{
|
||||
return mCompositorBridgeParent->ResetCompositor(aBackendHints, aOutIdentifier);
|
||||
return mCompositorBridgeParent->ResetCompositor(aBackendHints, aSeqNo, aOutIdentifier);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -30,7 +30,9 @@ public:
|
|||
CompositorBridgeParent* GetInProcessBridge() const override;
|
||||
void SetContentController(GeckoContentController* aController) override;
|
||||
RefPtr<IAPZCTreeManager> GetAPZCTreeManager() const override;
|
||||
bool Reset(const nsTArray<LayersBackend>& aBackendHints, TextureFactoryIdentifier* aOutIdentifier) override;
|
||||
bool Reset(const nsTArray<LayersBackend>& aBackendHints,
|
||||
uint64_t aSeqNo,
|
||||
TextureFactoryIdentifier* aOutIdentifier) override;
|
||||
void Shutdown() override;
|
||||
|
||||
private:
|
||||
|
|
|
@ -39,10 +39,10 @@ RemoteCompositorSession::~RemoteCompositorSession()
|
|||
}
|
||||
|
||||
void
|
||||
RemoteCompositorSession::NotifyDeviceReset()
|
||||
RemoteCompositorSession::NotifyDeviceReset(uint64_t aSeqNo)
|
||||
{
|
||||
MOZ_ASSERT(mWidget);
|
||||
mWidget->OnRenderingDeviceReset();
|
||||
mWidget->OnRenderingDeviceReset(aSeqNo);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -87,10 +87,12 @@ RemoteCompositorSession::GetAPZCTreeManager() const
|
|||
}
|
||||
|
||||
bool
|
||||
RemoteCompositorSession::Reset(const nsTArray<LayersBackend>& aBackendHints, TextureFactoryIdentifier* aOutIdentifier)
|
||||
RemoteCompositorSession::Reset(const nsTArray<LayersBackend>& aBackendHints,
|
||||
uint64_t aSeqNo,
|
||||
TextureFactoryIdentifier* aOutIdentifier)
|
||||
{
|
||||
bool didReset;
|
||||
Unused << mCompositorBridgeChild->SendReset(aBackendHints, &didReset, aOutIdentifier);
|
||||
Unused << mCompositorBridgeChild->SendReset(aBackendHints, aSeqNo, &didReset, aOutIdentifier);
|
||||
return didReset;
|
||||
}
|
||||
|
||||
|
|
|
@ -28,10 +28,12 @@ public:
|
|||
GeckoContentController* GetContentController();
|
||||
nsIWidget* GetWidget();
|
||||
RefPtr<IAPZCTreeManager> GetAPZCTreeManager() const override;
|
||||
bool Reset(const nsTArray<LayersBackend>& aBackendHints, TextureFactoryIdentifier* aOutIdentifier) override;
|
||||
bool Reset(const nsTArray<LayersBackend>& aBackendHints,
|
||||
uint64_t aSeqNo,
|
||||
TextureFactoryIdentifier* aOutIdentifier) override;
|
||||
void Shutdown() override;
|
||||
|
||||
void NotifyDeviceReset();
|
||||
void NotifyDeviceReset(uint64_t aSeqNo);
|
||||
void NotifySessionLost();
|
||||
|
||||
private:
|
||||
|
|
|
@ -338,12 +338,21 @@ CompositorBridgeChild::RecvInvalidateLayers(const uint64_t& aLayersId)
|
|||
|
||||
bool
|
||||
CompositorBridgeChild::RecvCompositorUpdated(const uint64_t& aLayersId,
|
||||
const TextureFactoryIdentifier& aNewIdentifier)
|
||||
const TextureFactoryIdentifier& aNewIdentifier,
|
||||
const uint64_t& aSeqNo)
|
||||
{
|
||||
if (mLayerManager) {
|
||||
// This case is handled directly by nsBaseWidget.
|
||||
MOZ_ASSERT(aLayersId == 0);
|
||||
} else if (aLayersId != 0) {
|
||||
// Update gfxPlatform if this is the first time we're seeing this compositor
|
||||
// update (we will get an update for each connected tab).
|
||||
static uint64_t sLastSeqNo = 0;
|
||||
if (sLastSeqNo != aSeqNo) {
|
||||
gfxPlatform::GetPlatform()->CompositorUpdated();
|
||||
sLastSeqNo = aSeqNo;
|
||||
}
|
||||
|
||||
if (dom::TabChild* child = dom::TabChild::GetFrom(aLayersId)) {
|
||||
child->CompositorUpdated(aNewIdentifier);
|
||||
}
|
||||
|
|
|
@ -103,7 +103,8 @@ public:
|
|||
|
||||
virtual bool
|
||||
RecvCompositorUpdated(const uint64_t& aLayersId,
|
||||
const TextureFactoryIdentifier& aNewIdentifier) override;
|
||||
const TextureFactoryIdentifier& aNewIdentifier,
|
||||
const uint64_t& aSeqNo) override;
|
||||
|
||||
virtual bool
|
||||
RecvOverfill(const uint32_t &aOverfill) override;
|
||||
|
|
|
@ -684,10 +684,13 @@ CompositorBridgeParent::Initialize()
|
|||
}
|
||||
|
||||
bool
|
||||
CompositorBridgeParent::RecvReset(nsTArray<LayersBackend>&& aBackendHints, bool* aResult, TextureFactoryIdentifier* aOutIdentifier)
|
||||
CompositorBridgeParent::RecvReset(nsTArray<LayersBackend>&& aBackendHints,
|
||||
const uint64_t& aSeqNo,
|
||||
bool* aResult,
|
||||
TextureFactoryIdentifier* aOutIdentifier)
|
||||
{
|
||||
Maybe<TextureFactoryIdentifier> newIdentifier;
|
||||
ResetCompositorTask(aBackendHints, &newIdentifier);
|
||||
ResetCompositorTask(aBackendHints, aSeqNo, &newIdentifier);
|
||||
|
||||
if (newIdentifier) {
|
||||
*aResult = true;
|
||||
|
@ -2054,6 +2057,7 @@ CompositorBridgeParent::InvalidateRemoteLayers()
|
|||
|
||||
bool
|
||||
CompositorBridgeParent::ResetCompositor(const nsTArray<LayersBackend>& aBackendHints,
|
||||
uint64_t aSeqNo,
|
||||
TextureFactoryIdentifier* aOutIdentifier)
|
||||
{
|
||||
Maybe<TextureFactoryIdentifier> newIdentifier;
|
||||
|
@ -2062,10 +2066,12 @@ CompositorBridgeParent::ResetCompositor(const nsTArray<LayersBackend>& aBackendH
|
|||
|
||||
CompositorLoop()->PostTask(NewRunnableMethod
|
||||
<StoreCopyPassByConstLRef<nsTArray<LayersBackend>>,
|
||||
Maybe<TextureFactoryIdentifier>*>(this,
|
||||
&CompositorBridgeParent::ResetCompositorTask,
|
||||
aBackendHints,
|
||||
&newIdentifier));
|
||||
uint64_t,
|
||||
Maybe<TextureFactoryIdentifier>*>(this,
|
||||
&CompositorBridgeParent::ResetCompositorTask,
|
||||
aBackendHints,
|
||||
aSeqNo,
|
||||
&newIdentifier));
|
||||
|
||||
mResetCompositorMonitor.Wait();
|
||||
}
|
||||
|
@ -2082,6 +2088,7 @@ CompositorBridgeParent::ResetCompositor(const nsTArray<LayersBackend>& aBackendH
|
|||
// monitor.
|
||||
void
|
||||
CompositorBridgeParent::ResetCompositorTask(const nsTArray<LayersBackend>& aBackendHints,
|
||||
uint64_t aSeqNo,
|
||||
Maybe<TextureFactoryIdentifier>* aOutNewIdentifier)
|
||||
{
|
||||
// Perform the reset inside a lock, so the main thread can wake up as soon as
|
||||
|
@ -2108,7 +2115,7 @@ CompositorBridgeParent::ResetCompositorTask(const nsTArray<LayersBackend>& aBack
|
|||
MonitorAutoLock lock(*sIndirectLayerTreesLock);
|
||||
ForEachIndirectLayerTree([&] (LayerTreeState* lts, uint64_t layersId) -> void {
|
||||
if (CrossProcessCompositorBridgeParent* cpcp = lts->mCrossProcessParent) {
|
||||
Unused << cpcp->SendCompositorUpdated(layersId, newIdentifier.value());
|
||||
Unused << cpcp->SendCompositorUpdated(layersId, newIdentifier.value(), aSeqNo);
|
||||
|
||||
if (LayerTransactionParent* ltp = lts->mLayerTree) {
|
||||
ltp->AddPendingCompositorUpdate();
|
||||
|
|
|
@ -262,7 +262,10 @@ public:
|
|||
bool Bind(Endpoint<PCompositorBridgeParent>&& aEndpoint);
|
||||
|
||||
virtual bool RecvInitialize(const uint64_t& aRootLayerTreeId) override;
|
||||
virtual bool RecvReset(nsTArray<LayersBackend>&& aBackendHints, bool* aResult, TextureFactoryIdentifier* aOutIdentifier) override;
|
||||
virtual bool RecvReset(nsTArray<LayersBackend>&& aBackendHints,
|
||||
const uint64_t& aSeqNo,
|
||||
bool* aResult,
|
||||
TextureFactoryIdentifier* aOutIdentifier) override;
|
||||
virtual bool RecvGetFrameUniformity(FrameUniformityData* aOutData) override;
|
||||
virtual bool RecvRequestOverfill() override;
|
||||
virtual bool RecvWillClose() override;
|
||||
|
@ -349,6 +352,7 @@ public:
|
|||
* minimize the amount of time the main thread is blocked.
|
||||
*/
|
||||
bool ResetCompositor(const nsTArray<LayersBackend>& aBackendHints,
|
||||
uint64_t aSeqNo,
|
||||
TextureFactoryIdentifier* aOutIdentifier);
|
||||
|
||||
/**
|
||||
|
@ -584,6 +588,7 @@ protected:
|
|||
|
||||
RefPtr<Compositor> NewCompositor(const nsTArray<LayersBackend>& aBackendHints);
|
||||
void ResetCompositorTask(const nsTArray<LayersBackend>& aBackendHints,
|
||||
uint64_t aSeqNo,
|
||||
Maybe<TextureFactoryIdentifier>* aOutNewIdentifier);
|
||||
Maybe<TextureFactoryIdentifier> ResetCompositorImpl(const nsTArray<LayersBackend>& aBackendHints);
|
||||
|
||||
|
|
|
@ -42,7 +42,11 @@ public:
|
|||
|
||||
// FIXME/bug 774388: work out what shutdown protocol we need.
|
||||
virtual bool RecvInitialize(const uint64_t& aRootLayerTreeId) override { return false; }
|
||||
virtual bool RecvReset(nsTArray<LayersBackend>&& aBackendHints, bool* aResult, TextureFactoryIdentifier* aOutIdentifier) override { return false; }
|
||||
virtual bool RecvReset(nsTArray<LayersBackend>&& aBackendHints,
|
||||
const uint64_t& aSeqNo,
|
||||
bool* aResult,
|
||||
TextureFactoryIdentifier* aOutIdentifier) override
|
||||
{ return false; }
|
||||
virtual bool RecvRequestOverfill() override { return true; }
|
||||
virtual bool RecvWillClose() override { return true; }
|
||||
virtual bool RecvPause() override { return true; }
|
||||
|
|
|
@ -62,8 +62,12 @@ child:
|
|||
|
||||
// The compositor type or device has changed, and a new texture factory
|
||||
// identifier is available. Layers must be invalidated and the new identifier
|
||||
// must be propagated.
|
||||
async CompositorUpdated(uint64_t layersId, TextureFactoryIdentifier newIdentifier);
|
||||
// must be propagated. The sequence number is a generation count for the
|
||||
// compositor.
|
||||
async CompositorUpdated(
|
||||
uint64_t layersId,
|
||||
TextureFactoryIdentifier newIdentifier,
|
||||
uint64_t seqNo);
|
||||
|
||||
// The compositor completed a layers transaction. id is the layers id
|
||||
// of the child layer tree that was composited (or 0 when notifying
|
||||
|
@ -123,7 +127,8 @@ parent:
|
|||
|
||||
// When out-of-process, this must be called to finish initialization.
|
||||
sync Initialize(uint64_t rootLayerTreeId);
|
||||
sync Reset(LayersBackend[] aBackendHints) returns (bool aResult, TextureFactoryIdentifier aOutIdentifier);
|
||||
sync Reset(LayersBackend[] aBackendHints, uint64_t aSeqNo)
|
||||
returns (bool aResult, TextureFactoryIdentifier aOutIdentifier);
|
||||
|
||||
// Returns whether this Compositor has APZ enabled or not.
|
||||
sync AsyncPanZoomEnabled(uint64_t layersId) returns (bool aHasAPZ);
|
||||
|
|
|
@ -313,7 +313,7 @@ void nsBaseWidget::DestroyLayerManager()
|
|||
}
|
||||
|
||||
void
|
||||
nsBaseWidget::OnRenderingDeviceReset()
|
||||
nsBaseWidget::OnRenderingDeviceReset(uint64_t aSeqNo)
|
||||
{
|
||||
if (!mLayerManager || !mCompositorSession) {
|
||||
return;
|
||||
|
@ -337,7 +337,7 @@ nsBaseWidget::OnRenderingDeviceReset()
|
|||
|
||||
// Recreate the compositor.
|
||||
TextureFactoryIdentifier identifier;
|
||||
if (!mCompositorSession->Reset(backendHints, &identifier)) {
|
||||
if (!mCompositorSession->Reset(backendHints, aSeqNo, &identifier)) {
|
||||
// No action was taken, so we don't have to do anything.
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -574,7 +574,7 @@ protected:
|
|||
void EnsureTextEventDispatcher();
|
||||
|
||||
// Notify the compositor that a device reset has occurred.
|
||||
void OnRenderingDeviceReset();
|
||||
void OnRenderingDeviceReset(uint64_t aSeqNo);
|
||||
|
||||
bool UseAPZ();
|
||||
|
||||
|
|
|
@ -1160,7 +1160,7 @@ nsWindow::EnumAllChildWindProc(HWND aWnd, LPARAM aParam)
|
|||
{
|
||||
nsWindow *wnd = WinUtils::GetNSWindowPtr(aWnd);
|
||||
if (wnd) {
|
||||
((nsWindow::WindowEnumCallback*)aParam)(wnd);
|
||||
reinterpret_cast<nsTArray<nsWindow*>*>(aParam)->AppendElement(wnd);
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
@ -1170,18 +1170,20 @@ nsWindow::EnumAllThreadWindowProc(HWND aWnd, LPARAM aParam)
|
|||
{
|
||||
nsWindow *wnd = WinUtils::GetNSWindowPtr(aWnd);
|
||||
if (wnd) {
|
||||
((nsWindow::WindowEnumCallback*)aParam)(wnd);
|
||||
reinterpret_cast<nsTArray<nsWindow*>*>(aParam)->AppendElement(wnd);
|
||||
}
|
||||
EnumChildWindows(aWnd, EnumAllChildWindProc, aParam);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void
|
||||
nsWindow::EnumAllWindows(WindowEnumCallback aCallback)
|
||||
/* static*/ nsTArray<nsWindow*>
|
||||
nsWindow::EnumAllWindows()
|
||||
{
|
||||
nsTArray<nsWindow*> windows;
|
||||
EnumThreadWindows(GetCurrentThreadId(),
|
||||
EnumAllThreadWindowProc,
|
||||
(LPARAM)aCallback);
|
||||
reinterpret_cast<LPARAM>(&windows));
|
||||
return windows;
|
||||
}
|
||||
|
||||
static already_AddRefed<SourceSurface>
|
||||
|
|
|
@ -254,8 +254,7 @@ public:
|
|||
WindowHook& GetWindowHook() { return mWindowHook; }
|
||||
nsWindow* GetParentWindow(bool aIncludeOwner);
|
||||
// Get an array of all nsWindow*s on the main thread.
|
||||
typedef void (WindowEnumCallback)(nsWindow*);
|
||||
static void EnumAllWindows(WindowEnumCallback aCallback);
|
||||
static nsTArray<nsWindow*> EnumAllWindows();
|
||||
|
||||
/**
|
||||
* Misc.
|
||||
|
|
|
@ -43,6 +43,7 @@ using mozilla::plugins::PluginInstanceParent;
|
|||
#include "nsDebug.h"
|
||||
#include "nsIXULRuntime.h"
|
||||
|
||||
#include "mozilla/gfx/GPUProcessManager.h"
|
||||
#include "mozilla/layers/CompositorBridgeParent.h"
|
||||
#include "mozilla/layers/CompositorBridgeChild.h"
|
||||
#include "ClientLayerManager.h"
|
||||
|
@ -172,16 +173,17 @@ bool nsWindow::OnPaint(HDC aDC, uint32_t aNestingLevel)
|
|||
|
||||
DeviceResetReason resetReason = DeviceResetReason::OK;
|
||||
if (gfxWindowsPlatform::GetPlatform()->DidRenderingDeviceReset(&resetReason)) {
|
||||
|
||||
gfxCriticalNote << "(nsWindow) Detected device reset: " << (int)resetReason;
|
||||
|
||||
gfxWindowsPlatform::GetPlatform()->UpdateRenderMode();
|
||||
EnumAllWindows([] (nsWindow* aWindow) -> void {
|
||||
aWindow->OnRenderingDeviceReset();
|
||||
});
|
||||
|
||||
uint64_t resetSeqNo = GPUProcessManager::Get()->GetNextDeviceResetSequenceNumber();
|
||||
nsTArray<nsWindow*> windows = EnumAllWindows();
|
||||
for (nsWindow* window : windows) {
|
||||
window->OnRenderingDeviceReset(resetSeqNo);
|
||||
}
|
||||
|
||||
gfxCriticalNote << "(nsWindow) Finished device reset.";
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче