Backed out changeset 4e515b6a5a41 (bug 702463)

This commit is contained in:
Jared Wein 2012-04-03 16:22:49 -07:00
parent 22084dbd86
commit 4ef699b55b
2 changed files with 31 additions and 60 deletions

View File

@ -1312,19 +1312,17 @@ NS_QUERYFRAME_TAIL_INHERITING(nsBoxFrame)
const double kCurrentVelocityWeighting = 0.25; const double kCurrentVelocityWeighting = 0.25;
const double kStopDecelerationWeighting = 0.4; const double kStopDecelerationWeighting = 0.4;
// AsyncScroll has ref counting. class nsGfxScrollFrameInner::AsyncScroll {
class nsGfxScrollFrameInner::AsyncScroll : public nsARefreshObserver {
public: public:
typedef mozilla::TimeStamp TimeStamp; typedef mozilla::TimeStamp TimeStamp;
typedef mozilla::TimeDuration TimeDuration; typedef mozilla::TimeDuration TimeDuration;
AsyncScroll() AsyncScroll():
: mIsFirstIteration(true) mIsFirstIteration(true)
, mCallee(nsnull) {}
{}
~AsyncScroll() { ~AsyncScroll() {
RemoveObserver(); if (mScrollTimer) mScrollTimer->Cancel();
} }
nsPoint PositionAt(TimeStamp aTime); nsPoint PositionAt(TimeStamp aTime);
@ -1338,6 +1336,7 @@ public:
return aTime > mStartTime + mDuration; // XXX or if we've hit the wall return aTime > mStartTime + mDuration; // XXX or if we've hit the wall
} }
nsCOMPtr<nsITimer> mScrollTimer;
TimeStamp mStartTime; TimeStamp mStartTime;
// mPrevStartTime holds previous 3 timestamps for intervals averaging (to // mPrevStartTime holds previous 3 timestamps for intervals averaging (to
@ -1383,51 +1382,6 @@ protected:
nscoord aDestination); nscoord aDestination);
void InitDuration(nsIAtom *aOrigin); void InitDuration(nsIAtom *aOrigin);
// The next section is observer/callback management
// Bodies of WillRefresh and RefreshDriver contain nsGfxScrollFrameInner specific code.
public:
NS_INLINE_DECL_REFCOUNTING(AsyncScroll)
/*
* Set a refresh observer for smooth scroll iterations (and start observing).
* Should be used at most once during the lifetime of this object.
* Return value: true on success, false otherwise.
*/
bool SetRefreshObserver(nsGfxScrollFrameInner *aCallee) {
NS_ASSERTION(aCallee && !mCallee, "AsyncScroll::SetRefreshObserver - Invalid usage.");
if (!RefreshDriver(aCallee)->AddRefreshObserver(this, Flush_Display)) {
return false;
}
mCallee = aCallee;
return true;
}
virtual void WillRefresh(mozilla::TimeStamp aTime) {
// The callback may release "this".
// We don't access members after returning, so no need for KungFuDeathGrip.
nsGfxScrollFrameInner::AsyncScrollCallback(mCallee, aTime);
}
private:
nsGfxScrollFrameInner *mCallee;
nsRefreshDriver* RefreshDriver(nsGfxScrollFrameInner* aCallee) {
return aCallee->mOuter->PresContext()->RefreshDriver();
}
/*
* The refresh driver doesn't hold a reference to its observers,
* so releasing this object can (and is) used to remove the observer on DTOR.
* Currently, this object is released once the scrolling ends.
*/
void RemoveObserver() {
if (mCallee) {
RefreshDriver(mCallee)->RemoveRefreshObserver(this, Flush_Display);
}
}
}; };
nsPoint nsPoint
@ -1641,6 +1595,7 @@ nsGfxScrollFrameInner::~nsGfxScrollFrameInner()
delete gScrollFrameActivityTracker; delete gScrollFrameActivityTracker;
gScrollFrameActivityTracker = nsnull; gScrollFrameActivityTracker = nsnull;
} }
delete mAsyncScroll;
if (mScrollActivityTimer) { if (mScrollActivityTimer) {
mScrollActivityTimer->Cancel(); mScrollActivityTimer->Cancel();
@ -1667,23 +1622,28 @@ nsGfxScrollFrameInner::ClampScrollPosition(const nsPoint& aPt) const
} }
/* /*
* Callback function from AsyncScroll, used in nsGfxScrollFrameInner::ScrollTo * Callback function from timer used in nsGfxScrollFrameInner::ScrollTo
*/ */
void void
nsGfxScrollFrameInner::AsyncScrollCallback(void* anInstance, mozilla::TimeStamp aTime) nsGfxScrollFrameInner::AsyncScrollCallback(nsITimer *aTimer, void* anInstance)
{ {
nsGfxScrollFrameInner* self = static_cast<nsGfxScrollFrameInner*>(anInstance); nsGfxScrollFrameInner* self = static_cast<nsGfxScrollFrameInner*>(anInstance);
if (!self || !self->mAsyncScroll) if (!self || !self->mAsyncScroll)
return; return;
if (self->mAsyncScroll->mIsSmoothScroll) { if (self->mAsyncScroll->mIsSmoothScroll) {
nsPoint destination = self->mAsyncScroll->PositionAt(aTime); TimeStamp now = TimeStamp::Now();
if (self->mAsyncScroll->IsFinished(aTime)) { nsPoint destination = self->mAsyncScroll->PositionAt(now);
if (self->mAsyncScroll->IsFinished(now)) {
delete self->mAsyncScroll;
self->mAsyncScroll = nsnull; self->mAsyncScroll = nsnull;
} }
self->ScrollToImpl(destination); self->ScrollToImpl(destination);
} else { } else {
delete self->mAsyncScroll;
self->mAsyncScroll = nsnull; self->mAsyncScroll = nsnull;
self->ScrollToImpl(self->mDestination); self->ScrollToImpl(self->mDestination);
} }
} }
@ -1706,6 +1666,7 @@ nsGfxScrollFrameInner::ScrollToWithOrigin(nsPoint aScrollPosition,
if (aMode == nsIScrollableFrame::INSTANT) { if (aMode == nsIScrollableFrame::INSTANT) {
// Asynchronous scrolling is not allowed, so we'll kill any existing // Asynchronous scrolling is not allowed, so we'll kill any existing
// async-scrolling process and do an instant scroll // async-scrolling process and do an instant scroll
delete mAsyncScroll;
mAsyncScroll = nsnull; mAsyncScroll = nsnull;
ScrollToImpl(mDestination); ScrollToImpl(mDestination);
return; return;
@ -1724,12 +1685,22 @@ nsGfxScrollFrameInner::ScrollToWithOrigin(nsPoint aScrollPosition,
} }
} else { } else {
mAsyncScroll = new AsyncScroll; mAsyncScroll = new AsyncScroll;
if (!mAsyncScroll->SetRefreshObserver(this)) { mAsyncScroll->mScrollTimer = do_CreateInstance("@mozilla.org/timer;1");
if (!mAsyncScroll->mScrollTimer) {
delete mAsyncScroll;
mAsyncScroll = nsnull; mAsyncScroll = nsnull;
// Observer setup failed. Scroll the normal way. // allocation failed. Scroll the normal way.
ScrollToImpl(mDestination); ScrollToImpl(mDestination);
return; return;
} }
if (isSmoothScroll) {
mAsyncScroll->mScrollTimer->InitWithFuncCallback(
AsyncScrollCallback, this, 1000 / 60,
nsITimer::TYPE_REPEATING_SLACK);
} else {
mAsyncScroll->mScrollTimer->InitWithFuncCallback(
AsyncScrollCallback, this, 0, nsITimer::TYPE_ONE_SHOT);
}
} }
mAsyncScroll->mIsSmoothScroll = isSmoothScroll; mAsyncScroll->mIsSmoothScroll = isSmoothScroll;

View File

@ -179,7 +179,7 @@ public:
nsPoint RestrictToDevPixels(const nsPoint& aPt, nsIntPoint* aPtDevPx, bool aShouldClamp) const; nsPoint RestrictToDevPixels(const nsPoint& aPt, nsIntPoint* aPtDevPx, bool aShouldClamp) const;
nsPoint ClampScrollPosition(const nsPoint& aPt) const; nsPoint ClampScrollPosition(const nsPoint& aPt) const;
static void AsyncScrollCallback(void* anInstance, mozilla::TimeStamp aTime); static void AsyncScrollCallback(nsITimer *aTimer, void* anInstance);
void ScrollTo(nsPoint aScrollPosition, nsIScrollableFrame::ScrollMode aMode) { void ScrollTo(nsPoint aScrollPosition, nsIScrollableFrame::ScrollMode aMode) {
ScrollToWithOrigin(aScrollPosition, aMode, nsGkAtoms::other); ScrollToWithOrigin(aScrollPosition, aMode, nsGkAtoms::other);
}; };
@ -288,7 +288,7 @@ public:
nsIBox* mScrollCornerBox; nsIBox* mScrollCornerBox;
nsIBox* mResizerBox; nsIBox* mResizerBox;
nsContainerFrame* mOuter; nsContainerFrame* mOuter;
nsRefPtr<AsyncScroll> mAsyncScroll; AsyncScroll* mAsyncScroll;
nsTArray<nsIScrollPositionListener*> mListeners; nsTArray<nsIScrollPositionListener*> mListeners;
nsRect mScrollPort; nsRect mScrollPort;
// Where we're currently scrolling to, if we're scrolling asynchronously. // Where we're currently scrolling to, if we're scrolling asynchronously.