Bug 864447 - Move timing tracking out of APZC; r=BenWa

This commit is contained in:
Anthony Jones 2013-07-09 17:53:16 +12:00
parent c97d98aca5
commit 1970c4cd22
5 changed files with 90 additions and 54 deletions

View File

@ -171,7 +171,6 @@ AsyncPanZoomController::AsyncPanZoomController(GeckoContentController* aGeckoCon
mMonitor("AsyncPanZoomController"),
mLastSampleTime(GetFrameTime()),
mState(NOTHING),
mPreviousPaintStartTime(GetFrameTime()),
mLastAsyncScrollTime(GetFrameTime()),
mLastAsyncScrollOffset(0, 0),
mCurrentAsyncScrollOffset(0, 0),
@ -179,7 +178,6 @@ AsyncPanZoomController::AsyncPanZoomController(GeckoContentController* aGeckoCon
mAsyncScrollThrottleTime(100),
mAsyncScrollTimeout(300),
mDPI(72),
mWaitingForContentToPaint(false),
mDisableNextTouchBatch(false),
mHandlingTouchQueue(false),
mDelayPanning(false)
@ -779,7 +777,7 @@ void AsyncPanZoomController::TrackTouch(const MultiTouchInput& aEvent) {
ScrollBy(CSSPoint::FromUnknownPoint(displacement));
ScheduleComposite();
TimeDuration timePaintDelta = GetFrameTime() - mPreviousPaintStartTime;
TimeDuration timePaintDelta = mPaintThrottler.TimeSinceLastRequest();
if (timePaintDelta.ToMilliseconds() > gPanRepaintInterval) {
RequestContentRepaint();
}
@ -816,7 +814,7 @@ bool AsyncPanZoomController::DoFling(const TimeDuration& aDelta) {
mX.GetDisplacementForDuration(inverseResolution.scale, aDelta),
mY.GetDisplacementForDuration(inverseResolution.scale, aDelta)
)));
TimeDuration timePaintDelta = GetFrameTime() - mPreviousPaintStartTime;
TimeDuration timePaintDelta = mPaintThrottler.TimeSinceLastRequest();
if (timePaintDelta.ToMilliseconds() > gFlingRepaintInterval) {
RequestContentRepaint();
}
@ -986,23 +984,11 @@ void AsyncPanZoomController::ScheduleComposite() {
}
void AsyncPanZoomController::RequestContentRepaint() {
mPreviousPaintStartTime = GetFrameTime();
double estimatedPaintSum = 0.0;
for (uint32_t i = 0; i < mPreviousPaintDurations.Length(); i++) {
estimatedPaintSum += mPreviousPaintDurations[i].ToSeconds();
}
double estimatedPaintDuration = 0.0;
if (estimatedPaintSum > EPSILON) {
estimatedPaintDuration = estimatedPaintSum / mPreviousPaintDurations.Length();
}
mFrameMetrics.mDisplayPort =
CalculatePendingDisplayPort(mFrameMetrics,
GetVelocityVector(),
GetAccelerationVector(),
estimatedPaintDuration);
mPaintThrottler.AverageDuration().ToSeconds());
// If we're trying to paint what we already think is painted, discard this
// request since it's a pointless paint.
@ -1042,10 +1028,10 @@ void AsyncPanZoomController::RequestContentRepaint() {
FROM_HERE,
NewRunnableMethod(mGeckoContentController.get(),
&GeckoContentController::RequestContentRepaint,
mFrameMetrics));
mFrameMetrics),
GetFrameTime());
mFrameMetrics.mPresShellId = mLastContentPaintMetrics.mPresShellId;
mLastPaintRequestMetrics = mFrameMetrics;
mWaitingForContentToPaint = true;
// Set the zoom back to what it was for the purpose of logic control.
mFrameMetrics.mZoom = actualZoom;
@ -1179,16 +1165,7 @@ void AsyncPanZoomController::NotifyLayersUpdated(const FrameMetrics& aViewportFr
mLastContentPaintMetrics = aViewportFrame;
mFrameMetrics.mMayHaveTouchListeners = aViewportFrame.mMayHaveTouchListeners;
if (mWaitingForContentToPaint) {
// Remove the oldest sample we have if adding a new sample takes us over our
// desired number of samples.
if (mPreviousPaintDurations.Length() >= gNumPaintDurationSamples) {
mPreviousPaintDurations.RemoveElementAt(0);
}
mPreviousPaintDurations.AppendElement(
GetFrameTime() - mPreviousPaintStartTime);
} else {
if (!mPaintThrottler.IsOutstanding()) {
// No paint was requested, but we got one anyways. One possible cause of this
// is that content could have fired a scrollTo(). In this case, we should take
// the new scroll offset. Document/viewport changes are handled elsewhere.
@ -1208,7 +1185,7 @@ void AsyncPanZoomController::NotifyLayersUpdated(const FrameMetrics& aViewportFr
}
}
mWaitingForContentToPaint = mPaintThrottler.TaskComplete();
mPaintThrottler.TaskComplete(GetFrameTime());
bool needContentRepaint = false;
if (aViewportFrame.mCompositionBounds.width == mFrameMetrics.mCompositionBounds.width &&
aViewportFrame.mCompositionBounds.height == mFrameMetrics.mCompositionBounds.height) {
@ -1221,7 +1198,8 @@ void AsyncPanZoomController::NotifyLayersUpdated(const FrameMetrics& aViewportFr
}
if (aIsFirstPaint || mFrameMetrics.IsDefault()) {
mPreviousPaintDurations.Clear();
mPaintThrottler.ClearHistory();
mPaintThrottler.SetMaxDurations(gNumPaintDurationSamples);
mX.CancelTouch();
mY.CancelTouch();

View File

@ -11,7 +11,6 @@
#include "mozilla/Attributes.h"
#include "mozilla/Monitor.h"
#include "mozilla/RefPtr.h"
#include "mozilla/TimeStamp.h"
#include "InputData.h"
#include "Axis.h"
#include "TaskThrottler.h"
@ -554,13 +553,6 @@ private:
// |mMonitor|; that is, it should be held whenever this is updated.
PanZoomState mState;
// How long it took in the past to paint after a series of previous requests.
nsTArray<TimeDuration> mPreviousPaintDurations;
// When the last paint request started. Used to determine the duration of
// previous paints.
TimeStamp mPreviousPaintStartTime;
// The last time and offset we fire the mozbrowserasyncscroll event when
// compositor has sampled the content transform for this frame.
TimeStamp mLastAsyncScrollTime;
@ -584,12 +576,6 @@ private:
int mDPI;
// Stores the current paint status of the frame that we're managing. Repaints
// may be triggered by other things (like content doing things), in which case
// this status will not be updated. It is only changed when this class
// requests a repaint.
bool mWaitingForContentToPaint;
// Flag used to determine whether or not we should disable handling of the
// next batch of touch events. This is used for sync scrolling of subframes.
bool mDisableNextTouchBatch;

View File

@ -18,7 +18,7 @@ TaskThrottler::TaskThrottler()
void
TaskThrottler::PostTask(const tracked_objects::Location& aLocation,
CancelableTask* aTask)
CancelableTask* aTask, const TimeStamp& aTimeStamp)
{
aTask->SetBirthPlace(aLocation);
@ -28,22 +28,53 @@ TaskThrottler::PostTask(const tracked_objects::Location& aLocation,
}
mQueuedTask = aTask;
} else {
mStartTime = aTimeStamp;
aTask->Run();
delete aTask;
mOutstanding = true;
}
}
bool
TaskThrottler::TaskComplete()
void
TaskThrottler::TaskComplete(const TimeStamp& aTimeStamp)
{
if (!mOutstanding) {
return;
}
// Remove the oldest sample we have if adding a new sample takes us over our
// desired number of samples.
if (mDurations.Length() >= mMaxDurations) {
mDurations.RemoveElementAt(0);
}
if (mMaxDurations) {
mDurations.AppendElement(aTimeStamp - mStartTime);
}
if (mQueuedTask) {
mStartTime = aTimeStamp;
mQueuedTask->Run();
mQueuedTask = nullptr;
return true;
} else {
mOutstanding = false;
}
mOutstanding = false;
return false;
}
TimeDuration
TaskThrottler::AverageDuration()
{
TimeDuration durationSum;
for (uint32_t i = 0; i < mDurations.Length(); i++) {
durationSum += mDurations[i];
}
return durationSum / mDurations.Length();
}
TimeDuration
TaskThrottler::TimeSinceLastRequest(const TimeStamp& aTimeStamp)
{
return aTimeStamp - mStartTime;
}
}

View File

@ -8,6 +8,8 @@
#define mozilla_dom_TaskThrottler_h
#include "nsAutoPtr.h"
#include "nsTArray.h"
#include "mozilla/TimeStamp.h"
class CancelableTask;
namespace tracked_objects {
@ -42,15 +44,51 @@ public:
* obsolete or the TaskThrottler is destructed.
*/
void PostTask(const tracked_objects::Location& aLocation,
CancelableTask* aTask);
CancelableTask* aTask, const TimeStamp& aTimeStamp);
/**
* return true if Throttler had outstanding task
* Mark the task as complete and process the next queued task.
*/
bool TaskComplete();
void TaskComplete(const TimeStamp& aTimeStamp);
/**
* Calculate the average time between processing the posted task and getting
* the TaskComplete() call back.
*/
TimeDuration AverageDuration();
/**
* return true if Throttler has an outstanding task
*/
bool IsOutstanding() { return mOutstanding; }
/**
* Return the time elapsed since the last request was processed
*/
TimeDuration TimeSinceLastRequest(const TimeStamp& aTimeStamp =
TimeStamp::Now());
/**
* Clear average history.
*/
void ClearHistory() { mDurations.Clear(); }
/**
* @param aMaxDurations The maximum number of durations to measure.
*/
void SetMaxDurations(uint32_t aMaxDurations)
{
mMaxDurations = aMaxDurations;
}
private:
bool mOutstanding;
nsAutoPtr<CancelableTask> mQueuedTask;
TimeStamp mStartTime;
// How long it took in the past to paint after a series of previous requests.
nsTArray<TimeDuration> mDurations;
uint32_t mMaxDurations;
};
}

View File

@ -111,6 +111,9 @@ public:
TimeDuration operator*(const int64_t aMultiplier) const {
return TimeDuration::FromTicks(mValue * int64_t(aMultiplier));
}
TimeDuration operator/(const int64_t aDivisor) const {
return TimeDuration::FromTicks(mValue / aDivisor);
}
double operator/(const TimeDuration& aOther) {
return static_cast<double>(mValue) / aOther.mValue;
}