Skip to content

Commit

Permalink
Update the animation callback histogram to measure only the delay bet…
Browse files Browse the repository at this point in the history
…ween post and invocation

This avoids abusing a histogram to keep both counts and times (this histogram stores only times) and lets us see the full distribution.

BUG=71256
TEST=

Review URL: http://codereview.chromium.org/6547001

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@75447 0039d316-1c4b-4281-b951-d872f2087c98
  • Loading branch information
jamesr@chromium.org committed Feb 18, 2011
1 parent c60940c commit 7c4329e
Showing 1 changed file with 46 additions and 33 deletions.
79 changes: 46 additions & 33 deletions chrome/renderer/render_widget.cc
Original file line number Diff line number Diff line change
Expand Up @@ -484,44 +484,57 @@ void RenderWidget::PaintDebugBorder(const gfx::Rect& rect,

void RenderWidget::AnimationCallback() {
animation_task_posted_ = false;
UMA_HISTOGRAM_CUSTOM_COUNTS("Renderer4.AnimationDelayTime", 0, 0, 16, 17);
if (!animation_update_pending_)
return;
if (!animation_floor_time_.is_null()) {
// Record when we fired (according to base::Time::Now()) relative to when
// we posted the task to quantify how much the base::Time/base::TimeTicks
// skew is affecting animations.
base::TimeDelta animation_callback_delay = base::Time::Now() -
(animation_floor_time_ - base::TimeDelta::FromMilliseconds(16));
UMA_HISTOGRAM_CUSTOM_TIMES("Renderer4.AnimationCallbackDelayTime",
animation_callback_delay,
base::TimeDelta::FromMilliseconds(0),
base::TimeDelta::FromMilliseconds(30),
25);
}
CallDoDeferredUpdate();
}

void RenderWidget::AnimateIfNeeded() {
if (animation_update_pending_) {
base::Time now = base::Time::Now();
if (now >= animation_floor_time_) {
animation_floor_time_ = now + base::TimeDelta::FromMilliseconds(16);
// Set a timer to call us back after 16ms (targetting 60FPS) before
// running animation callbacks so that if a callback requests another
// we'll be sure to run it at the proper time.
MessageLoop::current()->PostDelayedTask(FROM_HERE, NewRunnableMethod(
this, &RenderWidget::AnimationCallback), 16);
animation_task_posted_ = true;
animation_update_pending_ = false;
// Explicitly pump the WebCore Timer queue to avoid starvation on OS X.
// See crbug.com/71735.
// TODO(jamesr) Remove this call once crbug.com/72007 is fixed.
RenderThread::current()->GetWebKitClientImpl()->DoTimeout();
webwidget_->animate();
} else if (!animation_task_posted_) {
// This code uses base::Time::Now() to calculate the floor and next fire
// time because javascript's Date object uses base::Time::Now(). The
// message loop uses base::TimeTicks, which on windows can have a
// different granularity than base::Time.
// The upshot of all this is that this function might be called before
// base::Time::Now() has advanced past the animation_floor_time_. To
// avoid exposing this delay to javascript, we keep posting delayed
// tasks until base::Time::Now() has advanced far enough.
int64 delay = (animation_floor_time_ - now).InMillisecondsRoundedUp();
UMA_HISTOGRAM_CUSTOM_COUNTS("Renderer4.AnimationDelayTime",
static_cast<int>(delay), 0, 16, 17);
animation_task_posted_ = true;
MessageLoop::current()->PostDelayedTask(FROM_HERE, NewRunnableMethod(
this, &RenderWidget::AnimationCallback), delay);
}
if (!animation_update_pending_)
return;
base::Time now = base::Time::Now();
if (now >= animation_floor_time_) {
animation_floor_time_ = now + base::TimeDelta::FromMilliseconds(16);
// Set a timer to call us back after 16ms (targetting 60FPS) before
// running animation callbacks so that if a callback requests another
// we'll be sure to run it at the proper time.
MessageLoop::current()->PostDelayedTask(FROM_HERE, NewRunnableMethod(
this, &RenderWidget::AnimationCallback), 16);
animation_task_posted_ = true;
animation_update_pending_ = false;
// Explicitly pump the WebCore Timer queue to avoid starvation on OS X.
// See crbug.com/71735.
// TODO(jamesr) Remove this call once crbug.com/72007 is fixed.
RenderThread::current()->GetWebKitClientImpl()->DoTimeout();
webwidget_->animate();
return;
}
if (animation_task_posted_)
return;
// This code uses base::Time::Now() to calculate the floor and next fire
// time because javascript's Date object uses base::Time::Now(). The
// message loop uses base::TimeTicks, which on windows can have a
// different granularity than base::Time.
// The upshot of all this is that this function might be called before
// base::Time::Now() has advanced past the animation_floor_time_. To
// avoid exposing this delay to javascript, we keep posting delayed
// tasks until base::Time::Now() has advanced far enough.
int64 delay = (animation_floor_time_ - now).InMillisecondsRoundedUp();
animation_task_posted_ = true;
MessageLoop::current()->PostDelayedTask(FROM_HERE,
NewRunnableMethod(this, &RenderWidget::AnimationCallback), delay);
}

void RenderWidget::CallDoDeferredUpdate() {
Expand Down

0 comments on commit 7c4329e

Please sign in to comment.