Bug 1273737: Shutdown the refresh driver when there are no more refresh drivers. r=dbaron,mchang

This commit is contained in:
Kyle Huey 2016-06-06 06:51:15 -07:00
parent 6c0e1dc69f
commit da5496eedf
4 changed files with 40 additions and 24 deletions

View File

@ -330,14 +330,7 @@ nsPresContext::Destroy()
"nglayout.debug.paint_flashing_chrome",
this);
// Disconnect the refresh driver *after* the transition manager, which
// needs it.
if (mRefreshDriver) {
if (mRefreshDriver->PresContext() == this) {
mRefreshDriver->Disconnect();
}
mRefreshDriver = nullptr;
}
mRefreshDriver = nullptr;
}
nsPresContext::~nsPresContext()
@ -982,6 +975,10 @@ nsPresContext::SetShell(nsIPresShell* aShell)
mRestyleManager->Disconnect();
mRestyleManager = nullptr;
}
if (mRefreshDriver && mRefreshDriver->PresContext() == this) {
mRefreshDriver->Disconnect();
// Can't null out the refresh driver here.
}
if (IsRoot()) {
nsRootPresContext* thisRoot = static_cast<nsRootPresContext*>(this);

View File

@ -104,6 +104,11 @@ namespace {
// vsync to the main thread has been delayed by at least 2^i ms. Use
// GetJankLevels to grab a copy of this array.
uint64_t sJankLevels[12];
// The number outstanding nsRefreshDrivers (that have been created but not
// disconnected). When this reaches zero we will call
// nsRefreshDriver::Shutdown.
static uint32_t sRefreshDriverCount = 0;
}
namespace mozilla {
@ -889,11 +894,6 @@ GetFirstFrameDelay(imgIRequest* req)
return static_cast<uint32_t>(delay);
}
/* static */ void
nsRefreshDriver::InitializeStatics()
{
}
/* static */ void
nsRefreshDriver::Shutdown()
{
@ -1024,18 +1024,29 @@ nsRefreshDriver::nsRefreshDriver(nsPresContext* aPresContext)
mSkippedPaints(false),
mResizeSuppressed(false)
{
MOZ_ASSERT(NS_IsMainThread());
MOZ_ASSERT(mPresContext,
"Need a pres context to tell us to call Disconnect() later "
"and decrement sRefreshDriverCount.");
mMostRecentRefreshEpochTime = JS_Now();
mMostRecentRefresh = TimeStamp::Now();
mMostRecentTick = mMostRecentRefresh;
mNextThrottledFrameRequestTick = mMostRecentTick;
mNextRecomputeVisibilityTick = mMostRecentTick;
--sRefreshDriverCount;
}
nsRefreshDriver::~nsRefreshDriver()
{
MOZ_ASSERT(NS_IsMainThread());
MOZ_ASSERT(ObserverCount() == 0,
"observers should have unregistered");
MOZ_ASSERT(!mActiveTimer, "timer should be gone");
MOZ_ASSERT(!mPresContext,
"Should have called Disconnect() and decremented "
"sRefreshDriverCount!");
if (mRootRefresh) {
mRootRefresh->RemoveRefreshObserver(this, Flush_Style);
@ -2207,6 +2218,21 @@ nsRefreshDriver::CancelPendingEvents(nsIDocument* aDocument)
}
}
void
nsRefreshDriver::Disconnect()
{
MOZ_ASSERT(NS_IsMainThread());
StopTimer();
if (mPresContext) {
mPresContext = nullptr;
if (--sRefreshDriverCount == 0) {
Shutdown();
}
}
}
/* static */ bool
nsRefreshDriver::IsJankCritical()
{

View File

@ -77,9 +77,6 @@ public:
explicit nsRefreshDriver(nsPresContext *aPresContext);
~nsRefreshDriver();
static void InitializeStatics();
static void Shutdown();
/**
* Methods for testing, exposed via nsIDOMWindowUtils. See
* nsIDOMWindowUtils.advanceTimeAndRefresh for description.
@ -248,10 +245,7 @@ public:
* should stop its timer and forget about its pres context. This may
* be called from within a refresh.
*/
void Disconnect() {
StopTimer();
mPresContext = nullptr;
}
void Disconnect();
bool IsFrozen() { return mFreezeCount > 0; }
@ -334,6 +328,7 @@ public:
NS_IMETHOD_(MozExternalRefCountType) AddRef(void) override { return TransactionIdAllocator::AddRef(); }
NS_IMETHOD_(MozExternalRefCountType) Release(void) override { return TransactionIdAllocator::Release(); }
virtual void WillRefresh(mozilla::TimeStamp aTime) override;
private:
typedef nsTObserverArray<nsARefreshObserver*> ObserverArray;
typedef nsTHashtable<nsISupportsHashKey> RequestTable;
@ -463,6 +458,8 @@ private:
void ConfigureHighPrecision();
void SetHighPrecisionTimersEnabled(bool aEnable);
static void Shutdown();
// `true` if we are currently in jank-critical mode.
//
// In jank-critical mode, any iteration of the event loop that takes

View File

@ -109,7 +109,6 @@ using namespace mozilla::system;
#include "nsJSEnvironment.h"
#include "nsContentSink.h"
#include "nsFrameMessageManager.h"
#include "nsRefreshDriver.h"
#include "nsDOMMutationObserver.h"
#include "nsHyphenationManager.h"
#include "nsEditorSpellCheck.h"
@ -271,7 +270,6 @@ nsLayoutStatics::Initialize()
nsLayoutUtils::Initialize();
nsIPresShell::InitializeStatics();
TouchManager::InitializeStatics();
nsRefreshDriver::InitializeStatics();
nsPrincipal::InitializeStatics();
nsCORSListenerProxy::Startup();
@ -434,8 +432,6 @@ nsLayoutStatics::Shutdown()
ContentParent::ShutDown();
nsRefreshDriver::Shutdown();
DisplayItemClip::Shutdown();
nsDocument::XPCOMShutdown();