Backed out changeset 3366d180e8ee (bug 1145439) for test_scroll_event_ordering.html failures.

This commit is contained in:
Ryan VanderMeulen 2015-04-09 22:59:10 -04:00
parent 0c4f4dfd74
commit 5a3a69df0b
5 changed files with 52 additions and 189 deletions

View File

@ -3921,42 +3921,6 @@ nsIDocument::TakeFrameRequestCallbacks(FrameRequestCallbackList& aCallbacks)
mFrameRequestCallbacks.Clear();
}
bool
nsIDocument::ShouldThrottleFrameRequests()
{
if (!mIsShowing) {
// We're not showing (probably in a background tab or the bf cache).
return true;
}
if (!mPresShell) {
return false; // Can't do anything smarter.
}
nsIFrame* frame = mPresShell->GetRootFrame();
if (!frame) {
return false; // Can't do anything smarter.
}
nsIFrame* displayRootFrame = nsLayoutUtils::GetDisplayRootFrame(frame);
if (!displayRootFrame) {
return false; // Can't do anything smarter.
}
if (!displayRootFrame->DidPaintPresShell(mPresShell)) {
// We didn't get painted during the last paint, so we're not visible.
// Throttle. Note that because we have to paint this document at least
// once to unthrottle it, we will drop one requestAnimationFrame frame
// when a document that previously wasn't visible scrolls into view. This
// is acceptable since it would happen outside the viewport on APZ
// platforms and is unlikely to be human-perceivable on non-APZ platforms.
return true;
}
// We got painted during the last paint, so run at full speed.
return false;
}
PLDHashOperator RequestDiscardEnumerator(imgIRequest* aKey,
uint32_t aData,
void* userArg)

View File

@ -2103,13 +2103,6 @@ public:
*/
void TakeFrameRequestCallbacks(FrameRequestCallbackList& aCallbacks);
/**
* @return true if this document's frame request callbacks should be
* throttled. We throttle requestAnimationFrame for documents which aren't
* visible (e.g. scrolled out of the viewport).
*/
bool ShouldThrottleFrameRequests();
// This returns true when the document tree is being teared down.
bool InUnlinkOrDeletion() { return mInUnlinkOrDeletion; }

View File

@ -966,8 +966,8 @@ nsRefreshDriver::GetRegularTimerInterval(bool *outIsDefault) const
return 1000.0 / rate;
}
/* static */ double
nsRefreshDriver::GetThrottledTimerInterval()
double
nsRefreshDriver::GetThrottledTimerInterval() const
{
int32_t rate = Preferences::GetInt("layout.throttled_frame_rate", -1);
if (rate <= 0) {
@ -1020,8 +1020,6 @@ nsRefreshDriver::nsRefreshDriver(nsPresContext* aPresContext)
mPendingTransaction(0),
mCompletedTransaction(0),
mFreezeCount(0),
mThrottledFrameRequestInterval(TimeDuration::FromMilliseconds(
GetThrottledTimerInterval())),
mThrottled(false),
mTestControllingRefreshes(false),
mViewManagerFlushIsPending(false),
@ -1033,7 +1031,6 @@ nsRefreshDriver::nsRefreshDriver(nsPresContext* aPresContext)
mMostRecentRefreshEpochTime = JS_Now();
mMostRecentRefresh = TimeStamp::Now();
mMostRecentTick = mMostRecentRefresh;
mNextThrottledFrameRequestTick = mMostRecentTick;
}
nsRefreshDriver::~nsRefreshDriver()
@ -1257,15 +1254,13 @@ DisableHighPrecisionTimersCallback(nsITimer *aTimer, void *aClosure)
void
nsRefreshDriver::ConfigureHighPrecision()
{
bool haveUnthrottledFrameRequestCallbacks =
mFrameRequestCallbackDocs.Length() > 0;
bool haveFrameRequestCallbacks = mFrameRequestCallbackDocs.Length() > 0;
// if the only change that's needed is that we need high precision,
// then just set that
if (!mThrottled && !mRequestedHighPrecision &&
haveUnthrottledFrameRequestCallbacks) {
if (!mThrottled && !mRequestedHighPrecision && haveFrameRequestCallbacks) {
SetHighPrecisionTimersEnabled(true);
} else if (mRequestedHighPrecision && !haveUnthrottledFrameRequestCallbacks) {
} else if (mRequestedHighPrecision && !haveFrameRequestCallbacks) {
SetHighPrecisionTimersEnabled(false);
}
}
@ -1333,7 +1328,6 @@ nsRefreshDriver::ObserverCount() const
sum += mStyleFlushObservers.Length();
sum += mLayoutFlushObservers.Length();
sum += mFrameRequestCallbackDocs.Length();
sum += mThrottledFrameRequestCallbackDocs.Length();
sum += mViewManagerFlushIsPending;
return sum;
}
@ -1459,105 +1453,6 @@ static void GetProfileTimelineSubDocShells(nsDocShell* aRootDocShell,
};
}
static void
TakeFrameRequestCallbacksFrom(nsIDocument* aDocument,
nsTArray<DocumentFrameCallbacks>& aTarget)
{
aTarget.AppendElement(aDocument);
aDocument->TakeFrameRequestCallbacks(aTarget.LastElement().mCallbacks);
}
void
nsRefreshDriver::RunFrameRequestCallbacks(int64_t aNowEpoch, TimeStamp aNowTime)
{
// Grab all of our frame request callbacks up front.
nsTArray<DocumentFrameCallbacks>
frameRequestCallbacks(mFrameRequestCallbackDocs.Length() +
mThrottledFrameRequestCallbackDocs.Length());
// First, grab throttled frame request callbacks.
{
nsTArray<nsIDocument*> docsToRemove;
// We always tick throttled frame requests if the entire refresh driver is
// throttled, because in that situation throttled frame requests tick at the
// same frequency as non-throttled frame requests.
bool tickThrottledFrameRequests = mThrottled;
if (!tickThrottledFrameRequests &&
aNowTime >= mNextThrottledFrameRequestTick) {
mNextThrottledFrameRequestTick = aNowTime + mThrottledFrameRequestInterval;
tickThrottledFrameRequests = true;
}
for (nsIDocument* doc : mThrottledFrameRequestCallbackDocs) {
if (tickThrottledFrameRequests) {
// We're ticking throttled documents, so grab this document's requests.
// We don't bother appending to docsToRemove because we're going to
// clear mThrottledFrameRequestCallbackDocs anyway.
TakeFrameRequestCallbacksFrom(doc, frameRequestCallbacks);
} else if (!doc->ShouldThrottleFrameRequests()) {
// This document is no longer throttled, so grab its requests even
// though we're not ticking throttled frame requests right now. If
// this is the first unthrottled document with frame requests, we'll
// enter high precision mode the next time the callback is scheduled.
TakeFrameRequestCallbacksFrom(doc, frameRequestCallbacks);
docsToRemove.AppendElement(doc);
}
}
// Remove all the documents we're ticking from
// mThrottledFrameRequestCallbackDocs so they can be readded as needed.
if (tickThrottledFrameRequests) {
mThrottledFrameRequestCallbackDocs.Clear();
} else {
// XXX(seth): We're using this approach to avoid concurrent modification
// of mThrottledFrameRequestCallbackDocs. docsToRemove usually has either
// zero elements or a very small number, so this should be OK in practice.
for (nsIDocument* doc : docsToRemove) {
mThrottledFrameRequestCallbackDocs.RemoveElement(doc);
}
}
}
// Now grab unthrottled frame request callbacks.
for (nsIDocument* doc : mFrameRequestCallbackDocs) {
TakeFrameRequestCallbacksFrom(doc, frameRequestCallbacks);
}
// Reset mFrameRequestCallbackDocs so they can be readded as needed.
mFrameRequestCallbackDocs.Clear();
profiler_tracing("Paint", "Scripts", TRACING_INTERVAL_START);
int64_t eventTime = aNowEpoch / PR_USEC_PER_MSEC;
for (uint32_t i = 0; i < frameRequestCallbacks.Length(); ++i) {
const DocumentFrameCallbacks& docCallbacks = frameRequestCallbacks[i];
// XXXbz Bug 863140: GetInnerWindow can return the outer
// window in some cases.
nsPIDOMWindow* innerWindow = docCallbacks.mDocument->GetInnerWindow();
DOMHighResTimeStamp timeStamp = 0;
if (innerWindow && innerWindow->IsInnerWindow()) {
nsPerformance* perf = innerWindow->GetPerformance();
if (perf) {
timeStamp = perf->GetDOMTiming()->TimeStampToDOMHighRes(aNowTime);
}
// else window is partially torn down already
}
for (uint32_t j = 0; j < docCallbacks.mCallbacks.Length(); ++j) {
const nsIDocument::FrameRequestCallbackHolder& holder =
docCallbacks.mCallbacks[j];
nsAutoMicroTask mt;
if (holder.HasWebIDLCallback()) {
ErrorResult ignored;
holder.GetWebIDLCallback()->Call(timeStamp, ignored);
} else {
holder.GetXPCOMCallback()->Sample(eventTime);
}
}
}
profiler_tracing("Paint", "Scripts", TRACING_INTERVAL_END);
}
void
nsRefreshDriver::Tick(int64_t aNowEpoch, TimeStamp aNowTime)
{
@ -1648,7 +1543,46 @@ nsRefreshDriver::Tick(int64_t aNowEpoch, TimeStamp aNowTime)
if (i == 0) {
// This is the Flush_Style case.
RunFrameRequestCallbacks(aNowEpoch, aNowTime);
// Grab all of our frame request callbacks up front.
nsTArray<DocumentFrameCallbacks>
frameRequestCallbacks(mFrameRequestCallbackDocs.Length());
for (uint32_t i = 0; i < mFrameRequestCallbackDocs.Length(); ++i) {
frameRequestCallbacks.AppendElement(mFrameRequestCallbackDocs[i]);
mFrameRequestCallbackDocs[i]->
TakeFrameRequestCallbacks(frameRequestCallbacks.LastElement().mCallbacks);
}
// OK, now reset mFrameRequestCallbackDocs so they can be
// readded as needed.
mFrameRequestCallbackDocs.Clear();
profiler_tracing("Paint", "Scripts", TRACING_INTERVAL_START);
int64_t eventTime = aNowEpoch / PR_USEC_PER_MSEC;
for (uint32_t i = 0; i < frameRequestCallbacks.Length(); ++i) {
const DocumentFrameCallbacks& docCallbacks = frameRequestCallbacks[i];
// XXXbz Bug 863140: GetInnerWindow can return the outer
// window in some cases.
nsPIDOMWindow* innerWindow = docCallbacks.mDocument->GetInnerWindow();
DOMHighResTimeStamp timeStamp = 0;
if (innerWindow && innerWindow->IsInnerWindow()) {
nsPerformance* perf = innerWindow->GetPerformance();
if (perf) {
timeStamp = perf->GetDOMTiming()->TimeStampToDOMHighRes(aNowTime);
}
// else window is partially torn down already
}
for (uint32_t j = 0; j < docCallbacks.mCallbacks.Length(); ++j) {
const nsIDocument::FrameRequestCallbackHolder& holder =
docCallbacks.mCallbacks[j];
nsAutoMicroTask mt;
if (holder.HasWebIDLCallback()) {
ErrorResult ignored;
holder.GetWebIDLCallback()->Call(timeStamp, ignored);
} else {
holder.GetXPCOMCallback()->Sample(eventTime);
}
}
}
profiler_tracing("Paint", "Scripts", TRACING_INTERVAL_END);
if (mPresContext && mPresContext->GetPresShell()) {
bool tracingStyleFlush = false;
@ -2091,15 +2025,9 @@ void
nsRefreshDriver::ScheduleFrameRequestCallbacks(nsIDocument* aDocument)
{
NS_ASSERTION(mFrameRequestCallbackDocs.IndexOf(aDocument) ==
mFrameRequestCallbackDocs.NoIndex &&
mThrottledFrameRequestCallbackDocs.IndexOf(aDocument) ==
mThrottledFrameRequestCallbackDocs.NoIndex,
mFrameRequestCallbackDocs.NoIndex,
"Don't schedule the same document multiple times");
if (aDocument->ShouldThrottleFrameRequests()) {
mThrottledFrameRequestCallbackDocs.AppendElement(aDocument);
} else {
mFrameRequestCallbackDocs.AppendElement(aDocument);
}
mFrameRequestCallbackDocs.AppendElement(aDocument);
// make sure that the timer is running
ConfigureHighPrecision();
@ -2110,7 +2038,6 @@ void
nsRefreshDriver::RevokeFrameRequestCallbacks(nsIDocument* aDocument)
{
mFrameRequestCallbackDocs.RemoveElement(aDocument);
mThrottledFrameRequestCallbackDocs.RemoveElement(aDocument);
ConfigureHighPrecision();
// No need to worry about restarting our timer in slack mode if it's already
// running; that will happen automatically when it fires.

View File

@ -308,8 +308,6 @@ private:
};
typedef nsClassHashtable<nsUint32HashKey, ImageStartData> ImageStartTable;
void RunFrameRequestCallbacks(int64_t aNowEpoch, mozilla::TimeStamp aNowTime);
void Tick(int64_t aNowEpoch, mozilla::TimeStamp aNowTime);
enum EnsureTimerStartedFlags {
@ -338,7 +336,7 @@ private:
double GetRefreshTimerInterval() const;
double GetRegularTimerInterval(bool *outIsDefault = nullptr) const;
static double GetThrottledTimerInterval();
double GetThrottledTimerInterval() const;
bool HaveFrameRequestCallbacks() const {
return mFrameRequestCallbackDocs.Length() != 0;
@ -363,11 +361,6 @@ private:
uint64_t mCompletedTransaction;
uint32_t mFreezeCount;
// How long we wait between ticks for throttled (which generally means
// non-visible) documents registered with a non-throttled refresh driver.
const mozilla::TimeDuration mThrottledFrameRequestInterval;
bool mThrottled;
bool mTestControllingRefreshes;
bool mViewManagerFlushIsPending;
@ -386,7 +379,6 @@ private:
mozilla::TimeStamp mMostRecentRefresh;
mozilla::TimeStamp mMostRecentTick;
mozilla::TimeStamp mTickStart;
mozilla::TimeStamp mNextThrottledFrameRequestTick;
// separate arrays for each flush type we support
ObserverArray mObservers[3];
@ -398,7 +390,6 @@ private:
nsAutoTArray<nsIPresShell*, 16> mPresShellsToInvalidateIfHidden;
// nsTArray on purpose, because we want to be able to swap.
nsTArray<nsIDocument*> mFrameRequestCallbackDocs;
nsTArray<nsIDocument*> mThrottledFrameRequestCallbackDocs;
nsTArray<nsAPostRefreshObserver*> mPostRefreshObservers;
// Helper struct for processing image requests

View File

@ -2808,28 +2808,16 @@ NS_PTR_TO_INT32(frame->Properties().Get(nsIFrame::ParagraphDepthProperty()))
* the last repaint.
*/
void UpdatePaintCountForPaintedPresShells() {
for (nsWeakPtr& item : *PaintedPresShellList()) {
nsCOMPtr<nsIPresShell> shell = do_QueryReferent(item);
nsTArray<nsWeakPtr> * list = PaintedPresShellList();
for (int i = 0, l = list->Length(); i < l; i++) {
nsCOMPtr<nsIPresShell> shell = do_QueryReferent(list->ElementAt(i));
if (shell) {
shell->IncrementPaintCount();
}
}
}
/**
* @return true if we painted @aShell during the last repaint.
*/
bool DidPaintPresShell(nsIPresShell* aShell)
{
for (nsWeakPtr& item : *PaintedPresShellList()) {
nsCOMPtr<nsIPresShell> shell = do_QueryReferent(item);
if (shell == aShell) {
return true;
}
}
return false;
}
/**
* Accessors for the absolute containing block.
*/